Add GenericParam, refactor Generics in ast, hir, rustdoc
The Generics now contain one Vec of an enum for the generic parameters, rather than two separate Vec's for lifetime and type parameters. Additionally, places that previously used Vec<LifetimeDef> now use Vec<GenericParam> instead.
This commit is contained in:
parent
ab7abfcf34
commit
78493ed21a
51 changed files with 1020 additions and 832 deletions
|
@ -279,6 +279,9 @@ pub trait Visitor<'v> : Sized {
|
||||||
fn visit_ty(&mut self, t: &'v Ty) {
|
fn visit_ty(&mut self, t: &'v Ty) {
|
||||||
walk_ty(self, t)
|
walk_ty(self, t)
|
||||||
}
|
}
|
||||||
|
fn visit_generic_param(&mut self, p: &'v GenericParam) {
|
||||||
|
walk_generic_param(self, p)
|
||||||
|
}
|
||||||
fn visit_generics(&mut self, g: &'v Generics) {
|
fn visit_generics(&mut self, g: &'v Generics) {
|
||||||
walk_generics(self, g)
|
walk_generics(self, g)
|
||||||
}
|
}
|
||||||
|
@ -336,9 +339,6 @@ pub trait Visitor<'v> : Sized {
|
||||||
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
|
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
|
||||||
walk_lifetime(self, lifetime)
|
walk_lifetime(self, lifetime)
|
||||||
}
|
}
|
||||||
fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
|
|
||||||
walk_lifetime_def(self, lifetime)
|
|
||||||
}
|
|
||||||
fn visit_qpath(&mut self, qpath: &'v QPath, id: NodeId, span: Span) {
|
fn visit_qpath(&mut self, qpath: &'v QPath, id: NodeId, span: Span) {
|
||||||
walk_qpath(self, qpath, id, span)
|
walk_qpath(self, qpath, id, span)
|
||||||
}
|
}
|
||||||
|
@ -430,17 +430,12 @@ pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V, lifetime_def: &'v LifetimeDef) {
|
|
||||||
visitor.visit_lifetime(&lifetime_def.lifetime);
|
|
||||||
walk_list!(visitor, visit_lifetime, &lifetime_def.bounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
|
pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
|
||||||
trait_ref: &'v PolyTraitRef,
|
trait_ref: &'v PolyTraitRef,
|
||||||
_modifier: TraitBoundModifier)
|
_modifier: TraitBoundModifier)
|
||||||
where V: Visitor<'v>
|
where V: Visitor<'v>
|
||||||
{
|
{
|
||||||
walk_list!(visitor, visit_lifetime_def, &trait_ref.bound_lifetimes);
|
walk_list!(visitor, visit_generic_param, &trait_ref.bound_generic_params);
|
||||||
visitor.visit_trait_ref(&trait_ref.trait_ref);
|
visitor.visit_trait_ref(&trait_ref.trait_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,7 +576,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
|
||||||
}
|
}
|
||||||
TyBareFn(ref function_declaration) => {
|
TyBareFn(ref function_declaration) => {
|
||||||
visitor.visit_fn_decl(&function_declaration.decl);
|
visitor.visit_fn_decl(&function_declaration.decl);
|
||||||
walk_list!(visitor, visit_lifetime_def, &function_declaration.lifetimes);
|
walk_list!(visitor, visit_generic_param, &function_declaration.generic_params);
|
||||||
}
|
}
|
||||||
TyPath(ref qpath) => {
|
TyPath(ref qpath) => {
|
||||||
visitor.visit_qpath(qpath, typ.id, typ.span);
|
visitor.visit_qpath(qpath, typ.id, typ.span);
|
||||||
|
@ -729,14 +724,23 @@ pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyPar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
|
pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v GenericParam) {
|
||||||
for param in &generics.ty_params {
|
match *param {
|
||||||
visitor.visit_id(param.id);
|
GenericParam::Lifetime(ref ld) => {
|
||||||
visitor.visit_name(param.span, param.name);
|
visitor.visit_lifetime(&ld.lifetime);
|
||||||
walk_list!(visitor, visit_ty_param_bound, ¶m.bounds);
|
walk_list!(visitor, visit_lifetime, &ld.bounds);
|
||||||
walk_list!(visitor, visit_ty, ¶m.default);
|
|
||||||
}
|
}
|
||||||
walk_list!(visitor, visit_lifetime_def, &generics.lifetimes);
|
GenericParam::Type(ref ty_param) => {
|
||||||
|
visitor.visit_id(ty_param.id);
|
||||||
|
visitor.visit_name(ty_param.span, ty_param.name);
|
||||||
|
walk_list!(visitor, visit_ty_param_bound, &ty_param.bounds);
|
||||||
|
walk_list!(visitor, visit_ty, &ty_param.default);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
|
||||||
|
walk_list!(visitor, visit_generic_param, &generics.params);
|
||||||
visitor.visit_id(generics.where_clause.id);
|
visitor.visit_id(generics.where_clause.id);
|
||||||
walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates);
|
walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates);
|
||||||
}
|
}
|
||||||
|
@ -748,11 +752,11 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
|
||||||
match predicate {
|
match predicate {
|
||||||
&WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty,
|
&WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty,
|
||||||
ref bounds,
|
ref bounds,
|
||||||
ref bound_lifetimes,
|
ref bound_generic_params,
|
||||||
..}) => {
|
..}) => {
|
||||||
visitor.visit_ty(bounded_ty);
|
visitor.visit_ty(bounded_ty);
|
||||||
walk_list!(visitor, visit_ty_param_bound, bounds);
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||||
walk_list!(visitor, visit_lifetime_def, bound_lifetimes);
|
walk_list!(visitor, visit_generic_param, bound_generic_params);
|
||||||
}
|
}
|
||||||
&WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime,
|
&WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime,
|
||||||
ref bounds,
|
ref bounds,
|
||||||
|
|
|
@ -253,7 +253,9 @@ impl<'a> LoweringContext<'a> {
|
||||||
ItemKind::Ty(_, ref generics) |
|
ItemKind::Ty(_, ref generics) |
|
||||||
ItemKind::Trait(_, _, ref generics, ..) => {
|
ItemKind::Trait(_, _, ref generics, ..) => {
|
||||||
let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
|
let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
|
||||||
let count = generics.lifetimes.len();
|
let count = generics.params.iter()
|
||||||
|
.filter(|param| param.is_lifetime_param())
|
||||||
|
.count();
|
||||||
self.lctx.type_def_lifetime_params.insert(def_id, count);
|
self.lctx.type_def_lifetime_params.insert(def_id, count);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -306,8 +308,8 @@ impl<'a> LoweringContext<'a> {
|
||||||
let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node {
|
let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node {
|
||||||
hir::Item_::ItemImpl(_,_,_,ref generics,..) |
|
hir::Item_::ItemImpl(_,_,_,ref generics,..) |
|
||||||
hir::Item_::ItemTrait(_,_,ref generics,..) =>
|
hir::Item_::ItemTrait(_,_,ref generics,..) =>
|
||||||
generics.lifetimes.clone(),
|
generics.lifetimes().cloned().collect::<Vec<_>>(),
|
||||||
_ => Vec::new().into(),
|
_ => Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.lctx.with_parent_impl_lifetime_defs(&item_lifetimes, |this| {
|
self.lctx.with_parent_impl_lifetime_defs(&item_lifetimes, |this| {
|
||||||
|
@ -532,14 +534,14 @@ impl<'a> LoweringContext<'a> {
|
||||||
span.with_ctxt(SyntaxContext::empty().apply_mark(mark))
|
span.with_ctxt(SyntaxContext::empty().apply_mark(mark))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new hir::LifetimeDef for every new lifetime encountered
|
// Creates a new hir::GenericParam for every new lifetime and type parameter
|
||||||
// while evaluating `f`. Definitions are created with the parent provided.
|
// encountered while evaluating `f`. Definitions are created with the parent
|
||||||
// If no `parent_id` is provided, no definitions will be returned.
|
// provided. If no `parent_id` is provided, no definitions will be returned.
|
||||||
fn collect_in_band_defs<T, F>(
|
fn collect_in_band_defs<T, F>(
|
||||||
&mut self,
|
&mut self,
|
||||||
parent_id: Option<DefId>,
|
parent_id: Option<DefId>,
|
||||||
f: F
|
f: F
|
||||||
) -> (Vec<hir::TyParam>, Vec<hir::LifetimeDef>, T) where F: FnOnce(&mut LoweringContext) -> T
|
) -> (Vec<hir::GenericParam>, T) where F: FnOnce(&mut LoweringContext) -> T
|
||||||
{
|
{
|
||||||
assert!(!self.is_collecting_in_band_lifetimes);
|
assert!(!self.is_collecting_in_band_lifetimes);
|
||||||
assert!(self.lifetimes_to_define.is_empty());
|
assert!(self.lifetimes_to_define.is_empty());
|
||||||
|
@ -554,7 +556,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
let in_band_ty_params = self.in_band_ty_params.split_off(0);
|
let in_band_ty_params = self.in_band_ty_params.split_off(0);
|
||||||
let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
|
let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
|
||||||
|
|
||||||
let lifetime_defs = match parent_id {
|
let mut params = match parent_id {
|
||||||
Some(parent_id) => lifetimes_to_define.into_iter().map(|(span, name)| {
|
Some(parent_id) => lifetimes_to_define.into_iter().map(|(span, name)| {
|
||||||
let def_node_id = self.next_id().node_id;
|
let def_node_id = self.next_id().node_id;
|
||||||
|
|
||||||
|
@ -567,7 +569,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
Mark::root()
|
Mark::root()
|
||||||
);
|
);
|
||||||
|
|
||||||
hir::LifetimeDef {
|
hir::GenericParam::Lifetime(hir::LifetimeDef {
|
||||||
lifetime: hir::Lifetime {
|
lifetime: hir::Lifetime {
|
||||||
id: def_node_id,
|
id: def_node_id,
|
||||||
span,
|
span,
|
||||||
|
@ -576,12 +578,14 @@ impl<'a> LoweringContext<'a> {
|
||||||
bounds: Vec::new().into(),
|
bounds: Vec::new().into(),
|
||||||
pure_wrt_drop: false,
|
pure_wrt_drop: false,
|
||||||
in_band: true,
|
in_band: true,
|
||||||
}
|
})
|
||||||
}).collect(),
|
}).collect(),
|
||||||
None => Vec::new(),
|
None => Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
(in_band_ty_params, lifetime_defs, res)
|
params.extend(in_band_ty_params.into_iter().map(|tp| hir::GenericParam::Type(tp)));
|
||||||
|
|
||||||
|
(params, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluates `f` with the lifetimes in `lt_defs` in-scope.
|
// Evaluates `f` with the lifetimes in `lt_defs` in-scope.
|
||||||
|
@ -635,24 +639,24 @@ impl<'a> LoweringContext<'a> {
|
||||||
) -> (hir::Generics, T)
|
) -> (hir::Generics, T)
|
||||||
where F: FnOnce(&mut LoweringContext) -> T
|
where F: FnOnce(&mut LoweringContext) -> T
|
||||||
{
|
{
|
||||||
let (in_band_ty_defs, in_band_lifetime_defs, (mut lowered_generics, res)) =
|
let (in_band_defs, (mut lowered_generics, res)) =
|
||||||
self.with_in_scope_lifetime_defs(&generics.lifetimes, |this| {
|
self.with_in_scope_lifetime_defs(
|
||||||
|
&generics.params
|
||||||
|
.iter()
|
||||||
|
.filter_map(|p| match *p {
|
||||||
|
GenericParam::Lifetime(ref ld) => Some(ld.clone()),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
|this| {
|
||||||
this.collect_in_band_defs(parent_id, |this| {
|
this.collect_in_band_defs(parent_id, |this| {
|
||||||
(this.lower_generics(generics), f(this))
|
(this.lower_generics(generics), f(this))
|
||||||
})
|
})
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
lowered_generics.ty_params =
|
lowered_generics.params =
|
||||||
lowered_generics.ty_params
|
lowered_generics.params.iter().cloned().chain(in_band_defs).collect();
|
||||||
.iter().cloned()
|
|
||||||
.chain(in_band_ty_defs.into_iter())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
lowered_generics.lifetimes =
|
|
||||||
lowered_generics.lifetimes
|
|
||||||
.iter().cloned()
|
|
||||||
.chain(in_band_lifetime_defs.into_iter())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
(lowered_generics, res)
|
(lowered_generics, res)
|
||||||
}
|
}
|
||||||
|
@ -877,9 +881,16 @@ impl<'a> LoweringContext<'a> {
|
||||||
hir::TyRptr(lifetime, self.lower_mt(mt, itctx))
|
hir::TyRptr(lifetime, self.lower_mt(mt, itctx))
|
||||||
}
|
}
|
||||||
TyKind::BareFn(ref f) => {
|
TyKind::BareFn(ref f) => {
|
||||||
self.with_in_scope_lifetime_defs(&f.lifetimes, |this|
|
self.with_in_scope_lifetime_defs(
|
||||||
hir::TyBareFn(P(hir::BareFnTy {
|
&f.generic_params
|
||||||
lifetimes: this.lower_lifetime_defs(&f.lifetimes),
|
.iter()
|
||||||
|
.filter_map(|p| match *p {
|
||||||
|
GenericParam::Lifetime(ref ld) => Some(ld.clone()),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
|this| hir::TyBareFn(P(hir::BareFnTy {
|
||||||
|
generic_params: this.lower_generic_params(&f.generic_params, &NodeMap()),
|
||||||
unsafety: this.lower_unsafety(f.unsafety),
|
unsafety: this.lower_unsafety(f.unsafety),
|
||||||
abi: f.abi,
|
abi: f.abi,
|
||||||
decl: this.lower_fn_decl(&f.decl, None, false),
|
decl: this.lower_fn_decl(&f.decl, None, false),
|
||||||
|
@ -954,9 +965,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
|
|
||||||
hir::TyImplTraitExistential(hir::ExistTy {
|
hir::TyImplTraitExistential(hir::ExistTy {
|
||||||
generics: hir::Generics {
|
generics: hir::Generics {
|
||||||
lifetimes: lifetime_defs,
|
params: lifetime_defs,
|
||||||
// Type parameters are taken from environment:
|
|
||||||
ty_params: Vec::new().into(),
|
|
||||||
where_clause: hir::WhereClause {
|
where_clause: hir::WhereClause {
|
||||||
id: self.next_id().node_id,
|
id: self.next_id().node_id,
|
||||||
predicates: Vec::new().into(),
|
predicates: Vec::new().into(),
|
||||||
|
@ -1027,7 +1036,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
parent_index: DefIndex,
|
parent_index: DefIndex,
|
||||||
bounds: &hir::TyParamBounds
|
bounds: &hir::TyParamBounds
|
||||||
) -> (HirVec<hir::Lifetime>, HirVec<hir::LifetimeDef>) {
|
) -> (HirVec<hir::Lifetime>, HirVec<hir::GenericParam>) {
|
||||||
|
|
||||||
// This visitor walks over impl trait bounds and creates defs for all lifetimes which
|
// This visitor walks over impl trait bounds and creates defs for all lifetimes which
|
||||||
// appear in the bounds, excluding lifetimes that are created within the bounds.
|
// appear in the bounds, excluding lifetimes that are created within the bounds.
|
||||||
|
@ -1039,7 +1048,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
currently_bound_lifetimes: Vec<hir::LifetimeName>,
|
currently_bound_lifetimes: Vec<hir::LifetimeName>,
|
||||||
already_defined_lifetimes: HashSet<hir::LifetimeName>,
|
already_defined_lifetimes: HashSet<hir::LifetimeName>,
|
||||||
output_lifetimes: Vec<hir::Lifetime>,
|
output_lifetimes: Vec<hir::Lifetime>,
|
||||||
output_lifetime_defs: Vec<hir::LifetimeDef>,
|
output_lifetime_params: Vec<hir::GenericParam>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r, 'a: 'r, 'v> hir::intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a> {
|
impl<'r, 'a: 'r, 'v> hir::intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a> {
|
||||||
|
@ -1078,7 +1087,8 @@ impl<'a> LoweringContext<'a> {
|
||||||
let old_len = self.currently_bound_lifetimes.len();
|
let old_len = self.currently_bound_lifetimes.len();
|
||||||
|
|
||||||
// Record the introduction of 'a in `for<'a> ...`
|
// Record the introduction of 'a in `for<'a> ...`
|
||||||
for lt_def in &polytr.bound_lifetimes {
|
for param in &polytr.bound_generic_params {
|
||||||
|
if let hir::GenericParam::Lifetime(ref lt_def) = *param {
|
||||||
// Introduce lifetimes one at a time so that we can handle
|
// Introduce lifetimes one at a time so that we can handle
|
||||||
// cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`
|
// cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`
|
||||||
self.currently_bound_lifetimes.push(lt_def.lifetime.name);
|
self.currently_bound_lifetimes.push(lt_def.lifetime.name);
|
||||||
|
@ -1088,6 +1098,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
self.visit_lifetime(<_bound);
|
self.visit_lifetime(<_bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hir::intravisit::walk_trait_ref(self, &polytr.trait_ref);
|
hir::intravisit::walk_trait_ref(self, &polytr.trait_ref);
|
||||||
|
|
||||||
|
@ -1133,12 +1144,12 @@ impl<'a> LoweringContext<'a> {
|
||||||
span: lifetime.span,
|
span: lifetime.span,
|
||||||
name: name,
|
name: name,
|
||||||
};
|
};
|
||||||
self.output_lifetime_defs.push(hir::LifetimeDef {
|
self.output_lifetime_params.push(hir::GenericParam::Lifetime(hir::LifetimeDef {
|
||||||
lifetime: def_lifetime,
|
lifetime: def_lifetime,
|
||||||
bounds: Vec::new().into(),
|
bounds: Vec::new().into(),
|
||||||
pure_wrt_drop: false,
|
pure_wrt_drop: false,
|
||||||
in_band: false,
|
in_band: false,
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1150,7 +1161,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
currently_bound_lifetimes: Vec::new(),
|
currently_bound_lifetimes: Vec::new(),
|
||||||
already_defined_lifetimes: HashSet::new(),
|
already_defined_lifetimes: HashSet::new(),
|
||||||
output_lifetimes: Vec::new(),
|
output_lifetimes: Vec::new(),
|
||||||
output_lifetime_defs: Vec::new(),
|
output_lifetime_params: Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
|
@ -1159,7 +1170,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
|
|
||||||
(
|
(
|
||||||
lifetime_collector.output_lifetimes.into(),
|
lifetime_collector.output_lifetimes.into(),
|
||||||
lifetime_collector.output_lifetime_defs.into()
|
lifetime_collector.output_lifetime_params.into()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1568,13 +1579,6 @@ impl<'a> LoweringContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_ty_params(&mut self, tps: &Vec<TyParam>, add_bounds: &NodeMap<Vec<TyParamBound>>)
|
|
||||||
-> hir::HirVec<hir::TyParam> {
|
|
||||||
tps.iter().map(|tp| {
|
|
||||||
self.lower_ty_param(tp, add_bounds.get(&tp.id).map_or(&[][..], |x| &x))
|
|
||||||
}).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
|
fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
|
||||||
let name = match self.lower_ident(l.ident) {
|
let name = match self.lower_ident(l.ident) {
|
||||||
x if x == "'_" => hir::LifetimeName::Underscore,
|
x if x == "'_" => hir::LifetimeName::Underscore,
|
||||||
|
@ -1620,12 +1624,31 @@ impl<'a> LoweringContext<'a> {
|
||||||
lts.iter().map(|l| self.lower_lifetime(l)).collect()
|
lts.iter().map(|l| self.lower_lifetime(l)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_lifetime_defs(&mut self, lts: &Vec<LifetimeDef>) -> hir::HirVec<hir::LifetimeDef> {
|
fn lower_generic_params(
|
||||||
lts.iter().map(|l| self.lower_lifetime_def(l)).collect()
|
&mut self,
|
||||||
|
params: &Vec<GenericParam>,
|
||||||
|
add_bounds: &NodeMap<Vec<TyParamBound>>,
|
||||||
|
) -> hir::HirVec<hir::GenericParam> {
|
||||||
|
params.iter()
|
||||||
|
.map(|param| match *param {
|
||||||
|
GenericParam::Lifetime(ref lifetime_def) => {
|
||||||
|
hir::GenericParam::Lifetime(self.lower_lifetime_def(lifetime_def))
|
||||||
|
}
|
||||||
|
GenericParam::Type(ref ty_param) => {
|
||||||
|
hir::GenericParam::Type(self.lower_ty_param(
|
||||||
|
ty_param,
|
||||||
|
add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_generics(&mut self, g: &Generics) -> hir::Generics {
|
fn lower_generics(&mut self, g: &Generics) -> hir::Generics {
|
||||||
// Collect `?Trait` bounds in where clause and move them to parameter definitions.
|
// 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();
|
let mut add_bounds = NodeMap();
|
||||||
for pred in &g.where_clause.predicates {
|
for pred in &g.where_clause.predicates {
|
||||||
if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
|
if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
|
||||||
|
@ -1640,21 +1663,24 @@ impl<'a> LoweringContext<'a> {
|
||||||
match bound_pred.bounded_ty.node {
|
match bound_pred.bounded_ty.node {
|
||||||
TyKind::Path(None, ref path)
|
TyKind::Path(None, ref path)
|
||||||
if path.segments.len() == 1 &&
|
if path.segments.len() == 1 &&
|
||||||
bound_pred.bound_lifetimes.is_empty() => {
|
bound_pred.bound_generic_params.is_empty() => {
|
||||||
if let Some(Def::TyParam(def_id)) =
|
if let Some(Def::TyParam(def_id)) =
|
||||||
self.resolver.get_resolution(bound_pred.bounded_ty.id)
|
self.resolver.get_resolution(bound_pred.bounded_ty.id)
|
||||||
.map(|d| d.base_def()) {
|
.map(|d| d.base_def()) {
|
||||||
if let Some(node_id) =
|
if let Some(node_id) =
|
||||||
self.resolver.definitions().as_local_node_id(def_id) {
|
self.resolver.definitions().as_local_node_id(def_id) {
|
||||||
for ty_param in &g.ty_params {
|
for param in &g.params {
|
||||||
|
if let GenericParam::Type(ref ty_param) = *param {
|
||||||
if node_id == ty_param.id {
|
if node_id == ty_param.id {
|
||||||
add_bounds.entry(ty_param.id).or_insert(Vec::new())
|
add_bounds.entry(ty_param.id)
|
||||||
|
.or_insert(Vec::new())
|
||||||
.push(bound.clone());
|
.push(bound.clone());
|
||||||
continue 'next_bound;
|
continue 'next_bound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
report_error(self)
|
report_error(self)
|
||||||
}
|
}
|
||||||
_ => report_error(self)
|
_ => report_error(self)
|
||||||
|
@ -1665,8 +1691,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::Generics {
|
hir::Generics {
|
||||||
ty_params: self.lower_ty_params(&g.ty_params, &add_bounds),
|
params: self.lower_generic_params(&g.params, &add_bounds),
|
||||||
lifetimes: self.lower_lifetime_defs(&g.lifetimes),
|
|
||||||
where_clause: self.lower_where_clause(&g.where_clause),
|
where_clause: self.lower_where_clause(&g.where_clause),
|
||||||
span: g.span,
|
span: g.span,
|
||||||
}
|
}
|
||||||
|
@ -1684,13 +1709,21 @@ impl<'a> LoweringContext<'a> {
|
||||||
|
|
||||||
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate {
|
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate {
|
||||||
match *pred {
|
match *pred {
|
||||||
WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes,
|
WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_generic_params,
|
||||||
ref bounded_ty,
|
ref bounded_ty,
|
||||||
ref bounds,
|
ref bounds,
|
||||||
span}) => {
|
span}) => {
|
||||||
self.with_in_scope_lifetime_defs(bound_lifetimes, |this| {
|
self.with_in_scope_lifetime_defs(
|
||||||
|
&bound_generic_params.iter()
|
||||||
|
.filter_map(|p| match *p {
|
||||||
|
GenericParam::Lifetime(ref ld) => Some(ld.clone()),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
|this| {
|
||||||
hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
|
hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
|
||||||
bound_lifetimes: this.lower_lifetime_defs(bound_lifetimes),
|
bound_generic_params:
|
||||||
|
this.lower_generic_params(bound_generic_params, &NodeMap()),
|
||||||
bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::Disallowed),
|
bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::Disallowed),
|
||||||
bounds: bounds.iter().filter_map(|bound| match *bound {
|
bounds: bounds.iter().filter_map(|bound| match *bound {
|
||||||
// Ignore `?Trait` bounds.
|
// Ignore `?Trait` bounds.
|
||||||
|
@ -1701,7 +1734,8 @@ impl<'a> LoweringContext<'a> {
|
||||||
}).collect(),
|
}).collect(),
|
||||||
span,
|
span,
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime,
|
WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime,
|
||||||
ref bounds,
|
ref bounds,
|
||||||
|
@ -1761,12 +1795,19 @@ impl<'a> LoweringContext<'a> {
|
||||||
p: &PolyTraitRef,
|
p: &PolyTraitRef,
|
||||||
itctx: ImplTraitContext)
|
itctx: ImplTraitContext)
|
||||||
-> hir::PolyTraitRef {
|
-> hir::PolyTraitRef {
|
||||||
let bound_lifetimes = self.lower_lifetime_defs(&p.bound_lifetimes);
|
let bound_generic_params = self.lower_generic_params(&p.bound_generic_params, &NodeMap());
|
||||||
let trait_ref = self.with_parent_impl_lifetime_defs(&bound_lifetimes,
|
let trait_ref = self.with_parent_impl_lifetime_defs(
|
||||||
|this| this.lower_trait_ref(&p.trait_ref, itctx));
|
&bound_generic_params.iter()
|
||||||
|
.filter_map(|p| match *p {
|
||||||
|
hir::GenericParam::Lifetime(ref ld) => Some(ld.clone()),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
|this| this.lower_trait_ref(&p.trait_ref, itctx),
|
||||||
|
);
|
||||||
|
|
||||||
hir::PolyTraitRef {
|
hir::PolyTraitRef {
|
||||||
bound_lifetimes,
|
bound_generic_params,
|
||||||
trait_ref,
|
trait_ref,
|
||||||
span: p.span,
|
span: p.span,
|
||||||
}
|
}
|
||||||
|
@ -1945,11 +1986,19 @@ impl<'a> LoweringContext<'a> {
|
||||||
});
|
});
|
||||||
|
|
||||||
let new_impl_items = self.with_in_scope_lifetime_defs(
|
let new_impl_items = self.with_in_scope_lifetime_defs(
|
||||||
&ast_generics.lifetimes, |this| {
|
&ast_generics.params
|
||||||
|
.iter()
|
||||||
|
.filter_map(|p| match *p {
|
||||||
|
GenericParam::Lifetime(ref ld) => Some(ld.clone()),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
|this| {
|
||||||
impl_items.iter()
|
impl_items.iter()
|
||||||
.map(|item| this.lower_impl_item_ref(item))
|
.map(|item| this.lower_impl_item_ref(item))
|
||||||
.collect()
|
.collect()
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
hir::ItemImpl(self.lower_unsafety(unsafety),
|
hir::ItemImpl(self.lower_unsafety(unsafety),
|
||||||
|
@ -3621,7 +3670,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
// Turn trait object paths into `TyTraitObject` instead.
|
// Turn trait object paths into `TyTraitObject` instead.
|
||||||
if let Def::Trait(_) = path.def {
|
if let Def::Trait(_) = path.def {
|
||||||
let principal = hir::PolyTraitRef {
|
let principal = hir::PolyTraitRef {
|
||||||
bound_lifetimes: hir_vec![],
|
bound_generic_params: hir::HirVec::new(),
|
||||||
trait_ref: hir::TraitRef {
|
trait_ref: hir::TraitRef {
|
||||||
path: path.and_then(|path| path),
|
path: path.and_then(|path| path),
|
||||||
ref_id: id.node_id,
|
ref_id: id.node_id,
|
||||||
|
|
|
@ -326,7 +326,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_generics(&mut self, generics: &'hir Generics) {
|
fn visit_generics(&mut self, generics: &'hir Generics) {
|
||||||
for ty_param in generics.ty_params.iter() {
|
for ty_param in generics.ty_params() {
|
||||||
self.insert(ty_param.id, NodeTyParam(ty_param));
|
self.insert(ty_param.id, NodeTyParam(ty_param));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,14 +183,25 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_generics(&mut self, generics: &'a Generics) {
|
fn visit_generic_param(&mut self, param: &'a GenericParam) {
|
||||||
for ty_param in generics.ty_params.iter() {
|
match *param {
|
||||||
self.create_def(ty_param.id,
|
GenericParam::Lifetime(ref lifetime_def) => {
|
||||||
|
self.create_def(
|
||||||
|
lifetime_def.lifetime.id,
|
||||||
|
DefPathData::LifetimeDef(lifetime_def.lifetime.ident.name.as_str()),
|
||||||
|
REGULAR_SPACE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
GenericParam::Type(ref ty_param) => {
|
||||||
|
self.create_def(
|
||||||
|
ty_param.id,
|
||||||
DefPathData::TypeParam(ty_param.ident.name.as_str()),
|
DefPathData::TypeParam(ty_param.ident.name.as_str()),
|
||||||
REGULAR_SPACE);
|
REGULAR_SPACE
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
visit::walk_generics(self, generics);
|
visit::walk_generic_param(self, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_trait_item(&mut self, ti: &'a TraitItem) {
|
fn visit_trait_item(&mut self, ti: &'a TraitItem) {
|
||||||
|
@ -268,12 +279,6 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||||
visit::walk_ty(self, ty);
|
visit::walk_ty(self, ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_lifetime_def(&mut self, def: &'a LifetimeDef) {
|
|
||||||
self.create_def(def.lifetime.id,
|
|
||||||
DefPathData::LifetimeDef(def.lifetime.ident.name.as_str()),
|
|
||||||
REGULAR_SPACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||||
match stmt.node {
|
match stmt.node {
|
||||||
StmtKind::Mac(..) => self.visit_macro_invoc(stmt.id, false),
|
StmtKind::Mac(..) => self.visit_macro_invoc(stmt.id, false),
|
||||||
|
|
|
@ -48,6 +48,8 @@ use rustc_data_structures::indexed_vec;
|
||||||
use serialize::{self, Encoder, Encodable, Decoder, Decodable};
|
use serialize::{self, Encoder, Encodable, Decoder, Decodable};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::iter;
|
||||||
|
use std::slice;
|
||||||
|
|
||||||
/// HIR doesn't commit to a concrete storage type and has its own alias for a vector.
|
/// HIR doesn't commit to a concrete storage type and has its own alias for a vector.
|
||||||
/// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar
|
/// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar
|
||||||
|
@ -398,12 +400,67 @@ pub struct TyParam {
|
||||||
pub synthetic: Option<SyntheticTyParamKind>,
|
pub synthetic: Option<SyntheticTyParamKind>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GenericParamsExt {
|
||||||
|
fn lifetimes<'a>(&'a self) -> iter::FilterMap<
|
||||||
|
slice::Iter<GenericParam>,
|
||||||
|
fn(&GenericParam) -> Option<&LifetimeDef>,
|
||||||
|
>;
|
||||||
|
|
||||||
|
fn ty_params<'a>(&'a self) -> iter::FilterMap<
|
||||||
|
slice::Iter<GenericParam>,
|
||||||
|
fn(&GenericParam) -> Option<&TyParam>,
|
||||||
|
>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenericParamsExt for [GenericParam] {
|
||||||
|
fn lifetimes<'a>(&'a self) -> iter::FilterMap<
|
||||||
|
slice::Iter<GenericParam>,
|
||||||
|
fn(&GenericParam) -> Option<&LifetimeDef>,
|
||||||
|
> {
|
||||||
|
self.iter().filter_map(|param| match *param {
|
||||||
|
GenericParam::Lifetime(ref l) => Some(l),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ty_params<'a>(&'a self) -> iter::FilterMap<
|
||||||
|
slice::Iter<GenericParam>,
|
||||||
|
fn(&GenericParam) -> Option<&TyParam>,
|
||||||
|
> {
|
||||||
|
self.iter().filter_map(|param| match *param {
|
||||||
|
GenericParam::Type(ref t) => Some(t),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents lifetimes and type parameters attached to a declaration
|
/// Represents lifetimes and type parameters attached to a declaration
|
||||||
/// of a function, enum, trait, etc.
|
/// of a function, enum, trait, etc.
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
pub struct Generics {
|
pub struct Generics {
|
||||||
pub lifetimes: HirVec<LifetimeDef>,
|
pub params: HirVec<GenericParam>,
|
||||||
pub ty_params: HirVec<TyParam>,
|
|
||||||
pub where_clause: WhereClause,
|
pub where_clause: WhereClause,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
@ -411,8 +468,7 @@ pub struct Generics {
|
||||||
impl Generics {
|
impl Generics {
|
||||||
pub fn empty() -> Generics {
|
pub fn empty() -> Generics {
|
||||||
Generics {
|
Generics {
|
||||||
lifetimes: HirVec::new(),
|
params: HirVec::new(),
|
||||||
ty_params: HirVec::new(),
|
|
||||||
where_clause: WhereClause {
|
where_clause: WhereClause {
|
||||||
id: DUMMY_NODE_ID,
|
id: DUMMY_NODE_ID,
|
||||||
predicates: HirVec::new(),
|
predicates: HirVec::new(),
|
||||||
|
@ -422,15 +478,19 @@ impl Generics {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_lt_parameterized(&self) -> bool {
|
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 {
|
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 {
|
pub fn lifetimes<'a>(&'a self) -> impl Iterator<Item = &'a LifetimeDef> {
|
||||||
self.is_lt_parameterized() || self.is_type_parameterized()
|
self.params.lifetimes()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ty_params<'a>(&'a self) -> impl Iterator<Item = &'a TyParam> {
|
||||||
|
self.params.ty_params()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,17 +510,22 @@ impl UnsafeGeneric {
|
||||||
|
|
||||||
impl Generics {
|
impl Generics {
|
||||||
pub fn carries_unsafe_attr(&self) -> Option<UnsafeGeneric> {
|
pub fn carries_unsafe_attr(&self) -> Option<UnsafeGeneric> {
|
||||||
for r in &self.lifetimes {
|
for param in &self.params {
|
||||||
if r.pure_wrt_drop {
|
match *param {
|
||||||
return Some(UnsafeGeneric::Region(r.clone(), "may_dangle"));
|
GenericParam::Lifetime(ref l) => {
|
||||||
|
if l.pure_wrt_drop {
|
||||||
|
return Some(UnsafeGeneric::Region(l.clone(), "may_dangle"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for t in &self.ty_params {
|
GenericParam::Type(ref t) => {
|
||||||
if t.pure_wrt_drop {
|
if t.pure_wrt_drop {
|
||||||
return Some(UnsafeGeneric::Type(t.clone(), "may_dangle"));
|
return Some(UnsafeGeneric::Type(t.clone(), "may_dangle"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return None;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,8 +558,8 @@ pub enum WherePredicate {
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
pub struct WhereBoundPredicate {
|
pub struct WhereBoundPredicate {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
/// Any lifetimes from a `for` binding
|
/// Any generics from a `for` binding
|
||||||
pub bound_lifetimes: HirVec<LifetimeDef>,
|
pub bound_generic_params: HirVec<GenericParam>,
|
||||||
/// The type being bounded
|
/// The type being bounded
|
||||||
pub bounded_ty: P<Ty>,
|
pub bounded_ty: P<Ty>,
|
||||||
/// Trait and lifetime bounds (`Clone+Send+'static`)
|
/// Trait and lifetime bounds (`Clone+Send+'static`)
|
||||||
|
@ -1475,7 +1540,7 @@ pub enum PrimTy {
|
||||||
pub struct BareFnTy {
|
pub struct BareFnTy {
|
||||||
pub unsafety: Unsafety,
|
pub unsafety: Unsafety,
|
||||||
pub abi: Abi,
|
pub abi: Abi,
|
||||||
pub lifetimes: HirVec<LifetimeDef>,
|
pub generic_params: HirVec<GenericParam>,
|
||||||
pub decl: P<FnDecl>,
|
pub decl: P<FnDecl>,
|
||||||
pub arg_names: HirVec<Spanned<Name>>,
|
pub arg_names: HirVec<Spanned<Name>>,
|
||||||
}
|
}
|
||||||
|
@ -1733,7 +1798,7 @@ pub struct TraitRef {
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
pub struct PolyTraitRef {
|
pub struct PolyTraitRef {
|
||||||
/// The `'a` in `<'a> Foo<&'a T>`
|
/// The `'a` in `<'a> Foo<&'a T>`
|
||||||
pub bound_lifetimes: HirVec<LifetimeDef>,
|
pub bound_generic_params: HirVec<GenericParam>,
|
||||||
|
|
||||||
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
|
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
|
||||||
pub trait_ref: TraitRef,
|
pub trait_ref: TraitRef,
|
||||||
|
|
|
@ -390,16 +390,7 @@ impl<'a> State<'a> {
|
||||||
self.pclose()?;
|
self.pclose()?;
|
||||||
}
|
}
|
||||||
hir::TyBareFn(ref f) => {
|
hir::TyBareFn(ref f) => {
|
||||||
let generics = hir::Generics {
|
self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &f.generic_params,
|
||||||
lifetimes: f.lifetimes.clone(),
|
|
||||||
ty_params: hir::HirVec::new(),
|
|
||||||
where_clause: hir::WhereClause {
|
|
||||||
id: ast::DUMMY_NODE_ID,
|
|
||||||
predicates: hir::HirVec::new(),
|
|
||||||
},
|
|
||||||
span: syntax_pos::DUMMY_SP,
|
|
||||||
};
|
|
||||||
self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &generics,
|
|
||||||
&f.arg_names[..])?;
|
&f.arg_names[..])?;
|
||||||
}
|
}
|
||||||
hir::TyPath(ref qpath) => {
|
hir::TyPath(ref qpath) => {
|
||||||
|
@ -635,15 +626,15 @@ impl<'a> State<'a> {
|
||||||
self.s.word(&ga.asm.as_str())?;
|
self.s.word(&ga.asm.as_str())?;
|
||||||
self.end()?
|
self.end()?
|
||||||
}
|
}
|
||||||
hir::ItemTy(ref ty, ref params) => {
|
hir::ItemTy(ref ty, ref generics) => {
|
||||||
self.ibox(indent_unit)?;
|
self.ibox(indent_unit)?;
|
||||||
self.ibox(0)?;
|
self.ibox(0)?;
|
||||||
self.word_nbsp(&visibility_qualified(&item.vis, "type"))?;
|
self.word_nbsp(&visibility_qualified(&item.vis, "type"))?;
|
||||||
self.print_name(item.name)?;
|
self.print_name(item.name)?;
|
||||||
self.print_generics(params)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
self.end()?; // end the inner ibox
|
self.end()?; // end the inner ibox
|
||||||
|
|
||||||
self.print_where_clause(¶ms.where_clause)?;
|
self.print_where_clause(&generics.where_clause)?;
|
||||||
self.s.space()?;
|
self.s.space()?;
|
||||||
self.word_space("=")?;
|
self.word_space("=")?;
|
||||||
self.print_type(&ty)?;
|
self.print_type(&ty)?;
|
||||||
|
@ -686,8 +677,8 @@ impl<'a> State<'a> {
|
||||||
self.print_unsafety(unsafety)?;
|
self.print_unsafety(unsafety)?;
|
||||||
self.word_nbsp("impl")?;
|
self.word_nbsp("impl")?;
|
||||||
|
|
||||||
if generics.is_parameterized() {
|
if !generics.params.is_empty() {
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
self.s.space()?;
|
self.s.space()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -725,7 +716,7 @@ impl<'a> State<'a> {
|
||||||
self.print_unsafety(unsafety)?;
|
self.print_unsafety(unsafety)?;
|
||||||
self.word_nbsp("trait")?;
|
self.word_nbsp("trait")?;
|
||||||
self.print_name(item.name)?;
|
self.print_name(item.name)?;
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
let mut real_bounds = Vec::with_capacity(bounds.len());
|
let mut real_bounds = Vec::with_capacity(bounds.len());
|
||||||
for b in bounds.iter() {
|
for b in bounds.iter() {
|
||||||
if let TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
|
if let TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
|
||||||
|
@ -750,7 +741,7 @@ impl<'a> State<'a> {
|
||||||
self.print_visibility(&item.vis)?;
|
self.print_visibility(&item.vis)?;
|
||||||
self.word_nbsp("trait")?;
|
self.word_nbsp("trait")?;
|
||||||
self.print_name(item.name)?;
|
self.print_name(item.name)?;
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
let mut real_bounds = Vec::with_capacity(bounds.len());
|
let mut real_bounds = Vec::with_capacity(bounds.len());
|
||||||
// FIXME(durka) this seems to be some quite outdated syntax
|
// FIXME(durka) this seems to be some quite outdated syntax
|
||||||
for b in bounds.iter() {
|
for b in bounds.iter() {
|
||||||
|
@ -775,25 +766,20 @@ impl<'a> State<'a> {
|
||||||
self.print_path(&t.path, false)
|
self.print_path(&t.path, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_formal_lifetime_list(&mut self, lifetimes: &[hir::LifetimeDef]) -> io::Result<()> {
|
fn print_formal_generic_params(
|
||||||
if !lifetimes.is_empty() {
|
&mut self,
|
||||||
self.s.word("for<")?;
|
generic_params: &[hir::GenericParam]
|
||||||
let mut comma = false;
|
) -> io::Result<()> {
|
||||||
for lifetime_def in lifetimes {
|
if !generic_params.is_empty() {
|
||||||
if comma {
|
self.s.word("for")?;
|
||||||
self.word_space(",")?
|
self.print_generic_params(generic_params)?;
|
||||||
}
|
|
||||||
self.print_lifetime_def(lifetime_def)?;
|
|
||||||
comma = true;
|
|
||||||
}
|
|
||||||
self.s.word(">")?;
|
|
||||||
self.nbsp()?;
|
self.nbsp()?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef) -> io::Result<()> {
|
fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef) -> io::Result<()> {
|
||||||
self.print_formal_lifetime_list(&t.bound_lifetimes)?;
|
self.print_formal_generic_params(&t.bound_generic_params)?;
|
||||||
self.print_trait_ref(&t.trait_ref)
|
self.print_trait_ref(&t.trait_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,7 +792,7 @@ impl<'a> State<'a> {
|
||||||
-> io::Result<()> {
|
-> io::Result<()> {
|
||||||
self.head(&visibility_qualified(visibility, "enum"))?;
|
self.head(&visibility_qualified(visibility, "enum"))?;
|
||||||
self.print_name(name)?;
|
self.print_name(name)?;
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
self.print_where_clause(&generics.where_clause)?;
|
self.print_where_clause(&generics.where_clause)?;
|
||||||
self.s.space()?;
|
self.s.space()?;
|
||||||
self.print_variants(&enum_definition.variants, span)
|
self.print_variants(&enum_definition.variants, span)
|
||||||
|
@ -859,7 +845,7 @@ impl<'a> State<'a> {
|
||||||
print_finalizer: bool)
|
print_finalizer: bool)
|
||||||
-> io::Result<()> {
|
-> io::Result<()> {
|
||||||
self.print_name(name)?;
|
self.print_name(name)?;
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
if !struct_def.is_struct() {
|
if !struct_def.is_struct() {
|
||||||
if struct_def.is_tuple() {
|
if struct_def.is_tuple() {
|
||||||
self.popen()?;
|
self.popen()?;
|
||||||
|
@ -1941,7 +1927,7 @@ impl<'a> State<'a> {
|
||||||
self.nbsp()?;
|
self.nbsp()?;
|
||||||
self.print_name(name)?;
|
self.print_name(name)?;
|
||||||
}
|
}
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
|
|
||||||
self.popen()?;
|
self.popen()?;
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
@ -2056,31 +2042,19 @@ impl<'a> State<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_generics(&mut self, generics: &hir::Generics) -> io::Result<()> {
|
pub fn print_generic_params(&mut self, generic_params: &[hir::GenericParam]) -> io::Result<()> {
|
||||||
let total = generics.lifetimes.len() + generics.ty_params.len();
|
if !generic_params.is_empty() {
|
||||||
if total == 0 {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
self.s.word("<")?;
|
self.s.word("<")?;
|
||||||
|
|
||||||
let mut ints = Vec::new();
|
self.commasep(Inconsistent, generic_params, |s, param| {
|
||||||
for i in 0..total {
|
match *param {
|
||||||
ints.push(i);
|
hir::GenericParam::Lifetime(ref ld) => s.print_lifetime_def(ld),
|
||||||
}
|
hir::GenericParam::Type(ref tp) => s.print_ty_param(tp),
|
||||||
|
|
||||||
self.commasep(Inconsistent, &ints[..], |s, &idx| {
|
|
||||||
if idx < generics.lifetimes.len() {
|
|
||||||
let lifetime = &generics.lifetimes[idx];
|
|
||||||
s.print_lifetime_def(lifetime)
|
|
||||||
} else {
|
|
||||||
let idx = idx - generics.lifetimes.len();
|
|
||||||
let param = &generics.ty_params[idx];
|
|
||||||
s.print_ty_param(param)
|
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
self.s.word(">")?;
|
self.s.word(">")?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2111,11 +2085,13 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match predicate {
|
match predicate {
|
||||||
&hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{ref bound_lifetimes,
|
&hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
|
||||||
|
ref bound_generic_params,
|
||||||
ref bounded_ty,
|
ref bounded_ty,
|
||||||
ref bounds,
|
ref bounds,
|
||||||
..}) => {
|
..
|
||||||
self.print_formal_lifetime_list(bound_lifetimes)?;
|
}) => {
|
||||||
|
self.print_formal_generic_params(bound_generic_params)?;
|
||||||
self.print_type(&bounded_ty)?;
|
self.print_type(&bounded_ty)?;
|
||||||
self.print_bounds(":", bounds)?;
|
self.print_bounds(":", bounds)?;
|
||||||
}
|
}
|
||||||
|
@ -2184,17 +2160,16 @@ impl<'a> State<'a> {
|
||||||
unsafety: hir::Unsafety,
|
unsafety: hir::Unsafety,
|
||||||
decl: &hir::FnDecl,
|
decl: &hir::FnDecl,
|
||||||
name: Option<ast::Name>,
|
name: Option<ast::Name>,
|
||||||
generics: &hir::Generics,
|
generic_params: &[hir::GenericParam],
|
||||||
arg_names: &[Spanned<ast::Name>])
|
arg_names: &[Spanned<ast::Name>])
|
||||||
-> io::Result<()> {
|
-> io::Result<()> {
|
||||||
self.ibox(indent_unit)?;
|
self.ibox(indent_unit)?;
|
||||||
if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() {
|
if !generic_params.is_empty() {
|
||||||
self.s.word("for")?;
|
self.s.word("for")?;
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(generic_params)?;
|
||||||
}
|
}
|
||||||
let generics = hir::Generics {
|
let generics = hir::Generics {
|
||||||
lifetimes: hir::HirVec::new(),
|
params: hir::HirVec::new(),
|
||||||
ty_params: hir::HirVec::new(),
|
|
||||||
where_clause: hir::WhereClause {
|
where_clause: hir::WhereClause {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
predicates: hir::HirVec::new(),
|
predicates: hir::HirVec::new(),
|
||||||
|
|
|
@ -200,9 +200,13 @@ impl_stable_hash_for!(struct hir::TyParam {
|
||||||
synthetic
|
synthetic
|
||||||
});
|
});
|
||||||
|
|
||||||
|
impl_stable_hash_for!(enum hir::GenericParam {
|
||||||
|
Lifetime(lifetime_def),
|
||||||
|
Type(ty_param)
|
||||||
|
});
|
||||||
|
|
||||||
impl_stable_hash_for!(struct hir::Generics {
|
impl_stable_hash_for!(struct hir::Generics {
|
||||||
lifetimes,
|
params,
|
||||||
ty_params,
|
|
||||||
where_clause,
|
where_clause,
|
||||||
span
|
span
|
||||||
});
|
});
|
||||||
|
@ -224,7 +228,7 @@ impl_stable_hash_for!(enum hir::WherePredicate {
|
||||||
|
|
||||||
impl_stable_hash_for!(struct hir::WhereBoundPredicate {
|
impl_stable_hash_for!(struct hir::WhereBoundPredicate {
|
||||||
span,
|
span,
|
||||||
bound_lifetimes,
|
bound_generic_params,
|
||||||
bounded_ty,
|
bounded_ty,
|
||||||
bounds
|
bounds
|
||||||
});
|
});
|
||||||
|
@ -291,7 +295,7 @@ impl_stable_hash_for!(enum hir::PrimTy {
|
||||||
impl_stable_hash_for!(struct hir::BareFnTy {
|
impl_stable_hash_for!(struct hir::BareFnTy {
|
||||||
unsafety,
|
unsafety,
|
||||||
abi,
|
abi,
|
||||||
lifetimes,
|
generic_params,
|
||||||
decl,
|
decl,
|
||||||
arg_names
|
arg_names
|
||||||
});
|
});
|
||||||
|
@ -345,7 +349,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::TraitRef {
|
||||||
|
|
||||||
|
|
||||||
impl_stable_hash_for!(struct hir::PolyTraitRef {
|
impl_stable_hash_for!(struct hir::PolyTraitRef {
|
||||||
bound_lifetimes,
|
bound_generic_params,
|
||||||
trait_ref,
|
trait_ref,
|
||||||
span
|
span
|
||||||
});
|
});
|
||||||
|
|
|
@ -783,6 +783,11 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
||||||
hir_visit::walk_decl(self, d);
|
hir_visit::walk_decl(self, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam) {
|
||||||
|
run_lints!(self, check_generic_param, late_passes, p);
|
||||||
|
hir_visit::walk_generic_param(self, p);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_generics(&mut self, g: &'tcx hir::Generics) {
|
fn visit_generics(&mut self, g: &'tcx hir::Generics) {
|
||||||
run_lints!(self, check_generics, late_passes, g);
|
run_lints!(self, check_generics, late_passes, g);
|
||||||
hir_visit::walk_generics(self, g);
|
hir_visit::walk_generics(self, g);
|
||||||
|
@ -819,11 +824,6 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
||||||
hir_visit::walk_lifetime(self, lt);
|
hir_visit::walk_lifetime(self, lt);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_lifetime_def(&mut self, lt: &'tcx hir::LifetimeDef) {
|
|
||||||
run_lints!(self, check_lifetime_def, late_passes, lt);
|
|
||||||
hir_visit::walk_lifetime_def(self, lt);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_path(&mut self, p: &'tcx hir::Path, id: ast::NodeId) {
|
fn visit_path(&mut self, p: &'tcx hir::Path, id: ast::NodeId) {
|
||||||
run_lints!(self, check_path, late_passes, p, id);
|
run_lints!(self, check_path, late_passes, p, id);
|
||||||
hir_visit::walk_path(self, p);
|
hir_visit::walk_path(self, p);
|
||||||
|
@ -945,6 +945,11 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> {
|
||||||
run_lints!(self, check_expr_post, early_passes, e);
|
run_lints!(self, check_expr_post, early_passes, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
|
||||||
|
run_lints!(self, check_generic_param, early_passes, param);
|
||||||
|
ast_visit::walk_generic_param(self, param);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_generics(&mut self, g: &'a ast::Generics) {
|
fn visit_generics(&mut self, g: &'a ast::Generics) {
|
||||||
run_lints!(self, check_generics, early_passes, g);
|
run_lints!(self, check_generics, early_passes, g);
|
||||||
ast_visit::walk_generics(self, g);
|
ast_visit::walk_generics(self, g);
|
||||||
|
@ -971,10 +976,6 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> {
|
||||||
self.check_id(lt.id);
|
self.check_id(lt.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_lifetime_def(&mut self, lt: &'a ast::LifetimeDef) {
|
|
||||||
run_lints!(self, check_lifetime_def, early_passes, lt);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_path(&mut self, p: &'a ast::Path, id: ast::NodeId) {
|
fn visit_path(&mut self, p: &'a ast::Path, id: ast::NodeId) {
|
||||||
run_lints!(self, check_path, early_passes, p, id);
|
run_lints!(self, check_path, early_passes, p, id);
|
||||||
self.check_id(id);
|
self.check_id(id);
|
||||||
|
|
|
@ -155,6 +155,7 @@ pub trait LateLintPass<'a, 'tcx>: LintPass {
|
||||||
fn check_expr(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Expr) { }
|
fn check_expr(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Expr) { }
|
||||||
fn check_expr_post(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Expr) { }
|
fn check_expr_post(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Expr) { }
|
||||||
fn check_ty(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Ty) { }
|
fn check_ty(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Ty) { }
|
||||||
|
fn check_generic_param(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::GenericParam) { }
|
||||||
fn check_generics(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Generics) { }
|
fn check_generics(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Generics) { }
|
||||||
fn check_fn(&mut self,
|
fn check_fn(&mut self,
|
||||||
_: &LateContext<'a, 'tcx>,
|
_: &LateContext<'a, 'tcx>,
|
||||||
|
@ -196,7 +197,6 @@ pub trait LateLintPass<'a, 'tcx>: LintPass {
|
||||||
_: &'tcx hir::Variant,
|
_: &'tcx hir::Variant,
|
||||||
_: &'tcx hir::Generics) { }
|
_: &'tcx hir::Generics) { }
|
||||||
fn check_lifetime(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Lifetime) { }
|
fn check_lifetime(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Lifetime) { }
|
||||||
fn check_lifetime_def(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::LifetimeDef) { }
|
|
||||||
fn check_path(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Path, _: ast::NodeId) { }
|
fn check_path(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::Path, _: ast::NodeId) { }
|
||||||
fn check_attribute(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx ast::Attribute) { }
|
fn check_attribute(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx ast::Attribute) { }
|
||||||
|
|
||||||
|
@ -227,6 +227,7 @@ pub trait EarlyLintPass: LintPass {
|
||||||
fn check_expr(&mut self, _: &EarlyContext, _: &ast::Expr) { }
|
fn check_expr(&mut self, _: &EarlyContext, _: &ast::Expr) { }
|
||||||
fn check_expr_post(&mut self, _: &EarlyContext, _: &ast::Expr) { }
|
fn check_expr_post(&mut self, _: &EarlyContext, _: &ast::Expr) { }
|
||||||
fn check_ty(&mut self, _: &EarlyContext, _: &ast::Ty) { }
|
fn check_ty(&mut self, _: &EarlyContext, _: &ast::Ty) { }
|
||||||
|
fn check_generic_param(&mut self, _: &EarlyContext, _: &ast::GenericParam) { }
|
||||||
fn check_generics(&mut self, _: &EarlyContext, _: &ast::Generics) { }
|
fn check_generics(&mut self, _: &EarlyContext, _: &ast::Generics) { }
|
||||||
fn check_fn(&mut self, _: &EarlyContext,
|
fn check_fn(&mut self, _: &EarlyContext,
|
||||||
_: ast_visit::FnKind, _: &ast::FnDecl, _: Span, _: ast::NodeId) { }
|
_: ast_visit::FnKind, _: &ast::FnDecl, _: Span, _: ast::NodeId) { }
|
||||||
|
@ -244,7 +245,6 @@ pub trait EarlyLintPass: LintPass {
|
||||||
fn check_variant(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
|
fn check_variant(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
|
||||||
fn check_variant_post(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
|
fn check_variant_post(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
|
||||||
fn check_lifetime(&mut self, _: &EarlyContext, _: &ast::Lifetime) { }
|
fn check_lifetime(&mut self, _: &EarlyContext, _: &ast::Lifetime) { }
|
||||||
fn check_lifetime_def(&mut self, _: &EarlyContext, _: &ast::LifetimeDef) { }
|
|
||||||
fn check_path(&mut self, _: &EarlyContext, _: &ast::Path, _: ast::NodeId) { }
|
fn check_path(&mut self, _: &EarlyContext, _: &ast::Path, _: ast::NodeId) { }
|
||||||
fn check_attribute(&mut self, _: &EarlyContext, _: &ast::Attribute) { }
|
fn check_attribute(&mut self, _: &EarlyContext, _: &ast::Attribute) { }
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ use hir::intravisit;
|
||||||
// Returns true if the given set of generics implies that the item it's
|
// Returns true if the given set of generics implies that the item it's
|
||||||
// associated with must be inlined.
|
// associated with must be inlined.
|
||||||
fn generics_require_inlining(generics: &hir::Generics) -> bool {
|
fn generics_require_inlining(generics: &hir::Generics) -> bool {
|
||||||
!generics.ty_params.is_empty()
|
generics.params.iter().any(|param| param.is_type_param())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the given item must be inlined because it may be
|
// Returns true if the given item must be inlined because it may be
|
||||||
|
|
|
@ -33,7 +33,7 @@ use util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap, NodeSet};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
|
|
||||||
use hir;
|
use hir::{self, GenericParamsExt};
|
||||||
use hir::intravisit::{self, NestedVisitorMap, Visitor};
|
use hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||||
|
|
||||||
/// The origin of a named lifetime definition.
|
/// The origin of a named lifetime definition.
|
||||||
|
@ -491,19 +491,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let lifetimes = generics
|
let lifetimes = generics.lifetimes()
|
||||||
.lifetimes
|
|
||||||
.iter()
|
|
||||||
.map(|def| Region::early(&self.tcx.hir, &mut index, def))
|
.map(|def| Region::early(&self.tcx.hir, &mut index, def))
|
||||||
.collect();
|
.collect();
|
||||||
let next_early_index = index + generics.ty_params.len() as u32;
|
let next_early_index = index + generics.ty_params().count() as u32;
|
||||||
let scope = Scope::Binder {
|
let scope = Scope::Binder {
|
||||||
lifetimes,
|
lifetimes,
|
||||||
next_early_index,
|
next_early_index,
|
||||||
s: ROOT_SCOPE,
|
s: ROOT_SCOPE,
|
||||||
};
|
};
|
||||||
self.with(scope, |old_scope, this| {
|
self.with(scope, |old_scope, this| {
|
||||||
this.check_lifetime_defs(old_scope, &generics.lifetimes);
|
this.check_lifetime_params(old_scope, &generics.params);
|
||||||
intravisit::walk_item(this, item);
|
intravisit::walk_item(this, item);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -537,8 +535,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
let was_in_fn_syntax = self.is_in_fn_syntax;
|
let was_in_fn_syntax = self.is_in_fn_syntax;
|
||||||
self.is_in_fn_syntax = true;
|
self.is_in_fn_syntax = true;
|
||||||
let scope = Scope::Binder {
|
let scope = Scope::Binder {
|
||||||
lifetimes: c.lifetimes
|
lifetimes: c.generic_params
|
||||||
.iter()
|
.lifetimes()
|
||||||
.map(|def| Region::late(&self.tcx.hir, def))
|
.map(|def| Region::late(&self.tcx.hir, def))
|
||||||
.collect(),
|
.collect(),
|
||||||
s: self.scope,
|
s: self.scope,
|
||||||
|
@ -547,7 +545,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
self.with(scope, |old_scope, this| {
|
self.with(scope, |old_scope, this| {
|
||||||
// a bare fn has no bounds, so everything
|
// a bare fn has no bounds, so everything
|
||||||
// contained within is scoped within its binder.
|
// contained within is scoped within its binder.
|
||||||
this.check_lifetime_defs(old_scope, &c.lifetimes);
|
this.check_lifetime_params(old_scope, &c.generic_params);
|
||||||
intravisit::walk_ty(this, ty);
|
intravisit::walk_ty(this, ty);
|
||||||
});
|
});
|
||||||
self.is_in_fn_syntax = was_in_fn_syntax;
|
self.is_in_fn_syntax = was_in_fn_syntax;
|
||||||
|
@ -621,7 +619,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
|
|
||||||
let mut elision = None;
|
let mut elision = None;
|
||||||
let mut lifetimes = FxHashMap();
|
let mut lifetimes = FxHashMap();
|
||||||
for lt_def in &generics.lifetimes {
|
for lt_def in generics.lifetimes() {
|
||||||
let (lt_name, region) = Region::early(&self.tcx.hir, &mut index, <_def);
|
let (lt_name, region) = Region::early(&self.tcx.hir, &mut index, <_def);
|
||||||
if let hir::LifetimeName::Underscore = lt_name {
|
if let hir::LifetimeName::Underscore = lt_name {
|
||||||
// Pick the elided lifetime "definition" if one exists and use it to make an
|
// Pick the elided lifetime "definition" if one exists and use it to make an
|
||||||
|
@ -632,7 +630,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_early_index = index + generics.ty_params.len() as u32;
|
let next_early_index = index + generics.ty_params().count() as u32;
|
||||||
|
|
||||||
if let Some(elision_region) = elision {
|
if let Some(elision_region) = elision {
|
||||||
let scope = Scope::Elision {
|
let scope = Scope::Elision {
|
||||||
|
@ -678,11 +676,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
let generics = &trait_item.generics;
|
let generics = &trait_item.generics;
|
||||||
let mut index = self.next_early_index();
|
let mut index = self.next_early_index();
|
||||||
debug!("visit_ty: index = {}", index);
|
debug!("visit_ty: index = {}", index);
|
||||||
let lifetimes = generics.lifetimes.iter()
|
let lifetimes = generics.lifetimes()
|
||||||
.map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
|
.map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let next_early_index = index + generics.ty_params.len() as u32;
|
let next_early_index = index + generics.ty_params().count() as u32;
|
||||||
let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope };
|
let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope };
|
||||||
self.with(scope, |_old_scope, this| {
|
self.with(scope, |_old_scope, this| {
|
||||||
this.visit_generics(generics);
|
this.visit_generics(generics);
|
||||||
|
@ -696,7 +694,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
Const(_, _) => {
|
Const(_, _) => {
|
||||||
// Only methods and types support generics.
|
// Only methods and types support generics.
|
||||||
assert!(!trait_item.generics.is_parameterized());
|
assert!(trait_item.generics.params.is_empty());
|
||||||
intravisit::walk_trait_item(self, trait_item);
|
intravisit::walk_trait_item(self, trait_item);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -718,11 +716,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
let generics = &impl_item.generics;
|
let generics = &impl_item.generics;
|
||||||
let mut index = self.next_early_index();
|
let mut index = self.next_early_index();
|
||||||
debug!("visit_ty: index = {}", index);
|
debug!("visit_ty: index = {}", index);
|
||||||
let lifetimes = generics.lifetimes.iter()
|
let lifetimes = generics.lifetimes()
|
||||||
.map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
|
.map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let next_early_index = index + generics.ty_params.len() as u32;
|
let next_early_index = index + generics.ty_params().count() as u32;
|
||||||
let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope };
|
let scope = Scope::Binder { lifetimes, next_early_index, s: self.scope };
|
||||||
self.with(scope, |_old_scope, this| {
|
self.with(scope, |_old_scope, this| {
|
||||||
this.visit_generics(generics);
|
this.visit_generics(generics);
|
||||||
|
@ -731,7 +729,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
Const(_, _) => {
|
Const(_, _) => {
|
||||||
// Only methods and types support generics.
|
// Only methods and types support generics.
|
||||||
assert!(!impl_item.generics.is_parameterized());
|
assert!(impl_item.generics.params.is_empty());
|
||||||
intravisit::walk_impl_item(self, impl_item);
|
intravisit::walk_impl_item(self, impl_item);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -767,8 +765,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
||||||
check_mixed_explicit_and_in_band_defs(self.tcx, &generics.lifetimes);
|
check_mixed_explicit_and_in_band_defs(
|
||||||
for ty_param in generics.ty_params.iter() {
|
self.tcx,
|
||||||
|
&generics.lifetimes().cloned().collect::<Vec<_>>()
|
||||||
|
);
|
||||||
|
for ty_param in generics.ty_params() {
|
||||||
walk_list!(self, visit_ty_param_bound, &ty_param.bounds);
|
walk_list!(self, visit_ty_param_bound, &ty_param.bounds);
|
||||||
if let Some(ref ty) = ty_param.default {
|
if let Some(ref ty) = ty_param.default {
|
||||||
self.visit_ty(&ty);
|
self.visit_ty(&ty);
|
||||||
|
@ -779,22 +780,21 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
&hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
|
&hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
|
||||||
ref bounded_ty,
|
ref bounded_ty,
|
||||||
ref bounds,
|
ref bounds,
|
||||||
ref bound_lifetimes,
|
ref bound_generic_params,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
if !bound_lifetimes.is_empty() {
|
if bound_generic_params.iter().any(|p| p.is_lifetime_param()) {
|
||||||
self.trait_ref_hack = true;
|
self.trait_ref_hack = true;
|
||||||
let next_early_index = self.next_early_index();
|
let next_early_index = self.next_early_index();
|
||||||
let scope = Scope::Binder {
|
let scope = Scope::Binder {
|
||||||
lifetimes: bound_lifetimes
|
lifetimes: bound_generic_params.lifetimes()
|
||||||
.iter()
|
|
||||||
.map(|def| Region::late(&self.tcx.hir, def))
|
.map(|def| Region::late(&self.tcx.hir, def))
|
||||||
.collect(),
|
.collect(),
|
||||||
s: self.scope,
|
s: self.scope,
|
||||||
next_early_index,
|
next_early_index,
|
||||||
};
|
};
|
||||||
let result = self.with(scope, |old_scope, this| {
|
let result = self.with(scope, |old_scope, this| {
|
||||||
this.check_lifetime_defs(old_scope, bound_lifetimes);
|
this.check_lifetime_params(old_scope, &bound_generic_params);
|
||||||
this.visit_ty(&bounded_ty);
|
this.visit_ty(&bounded_ty);
|
||||||
walk_list!(this, visit_ty_param_bound, bounds);
|
walk_list!(this, visit_ty_param_bound, bounds);
|
||||||
});
|
});
|
||||||
|
@ -834,7 +834,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
) {
|
) {
|
||||||
debug!("visit_poly_trait_ref trait_ref={:?}", trait_ref);
|
debug!("visit_poly_trait_ref trait_ref={:?}", trait_ref);
|
||||||
|
|
||||||
if !self.trait_ref_hack || !trait_ref.bound_lifetimes.is_empty() {
|
if !self.trait_ref_hack ||
|
||||||
|
trait_ref.bound_generic_params.iter().any(|p| p.is_lifetime_param())
|
||||||
|
{
|
||||||
if self.trait_ref_hack {
|
if self.trait_ref_hack {
|
||||||
span_err!(
|
span_err!(
|
||||||
self.tcx.sess,
|
self.tcx.sess,
|
||||||
|
@ -845,19 +847,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
let next_early_index = self.next_early_index();
|
let next_early_index = self.next_early_index();
|
||||||
let scope = Scope::Binder {
|
let scope = Scope::Binder {
|
||||||
lifetimes: trait_ref
|
lifetimes: trait_ref.bound_generic_params
|
||||||
.bound_lifetimes
|
.lifetimes()
|
||||||
.iter()
|
|
||||||
.map(|def| Region::late(&self.tcx.hir, def))
|
.map(|def| Region::late(&self.tcx.hir, def))
|
||||||
.collect(),
|
.collect(),
|
||||||
s: self.scope,
|
s: self.scope,
|
||||||
next_early_index,
|
next_early_index,
|
||||||
};
|
};
|
||||||
self.with(scope, |old_scope, this| {
|
self.with(scope, |old_scope, this| {
|
||||||
this.check_lifetime_defs(old_scope, &trait_ref.bound_lifetimes);
|
this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params);
|
||||||
for lifetime in &trait_ref.bound_lifetimes {
|
walk_list!(this, visit_generic_param, &trait_ref.bound_generic_params);
|
||||||
this.visit_lifetime_def(lifetime);
|
|
||||||
}
|
|
||||||
this.visit_trait_ref(&trait_ref.trait_ref)
|
this.visit_trait_ref(&trait_ref.trait_ref)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -1087,8 +1086,9 @@ fn compute_object_lifetime_defaults(
|
||||||
.map(|set| match *set {
|
.map(|set| match *set {
|
||||||
Set1::Empty => "BaseDefault".to_string(),
|
Set1::Empty => "BaseDefault".to_string(),
|
||||||
Set1::One(Region::Static) => "'static".to_string(),
|
Set1::One(Region::Static) => "'static".to_string(),
|
||||||
Set1::One(Region::EarlyBound(i, _, _)) => generics.lifetimes
|
Set1::One(Region::EarlyBound(i, _, _)) => generics.lifetimes()
|
||||||
[i as usize]
|
.nth(i as usize)
|
||||||
|
.unwrap()
|
||||||
.lifetime
|
.lifetime
|
||||||
.name
|
.name
|
||||||
.name()
|
.name()
|
||||||
|
@ -1124,9 +1124,7 @@ fn object_lifetime_defaults_for_item(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generics
|
generics.ty_params()
|
||||||
.ty_params
|
|
||||||
.iter()
|
|
||||||
.map(|param| {
|
.map(|param| {
|
||||||
let mut set = Set1::Empty;
|
let mut set = Set1::Empty;
|
||||||
|
|
||||||
|
@ -1142,7 +1140,7 @@ fn object_lifetime_defaults_for_item(
|
||||||
|
|
||||||
// Ignore `for<'a> type: ...` as they can change what
|
// Ignore `for<'a> type: ...` as they can change what
|
||||||
// lifetimes mean (although we could "just" handle it).
|
// lifetimes mean (although we could "just" handle it).
|
||||||
if !data.bound_lifetimes.is_empty() {
|
if !data.bound_generic_params.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1163,8 +1161,7 @@ fn object_lifetime_defaults_for_item(
|
||||||
Set1::One(Region::Static)
|
Set1::One(Region::Static)
|
||||||
} else {
|
} else {
|
||||||
generics
|
generics
|
||||||
.lifetimes
|
.lifetimes()
|
||||||
.iter()
|
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|&(_, def)| def.lifetime.name == name)
|
.find(|&(_, def)| def.lifetime.name == name)
|
||||||
.map_or(Set1::Many, |(i, def)| {
|
.map_or(Set1::Many, |(i, def)| {
|
||||||
|
@ -1283,15 +1280,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
match parent.node {
|
match parent.node {
|
||||||
hir::ItemTrait(_, _, ref generics, ..)
|
hir::ItemTrait(_, _, ref generics, ..)
|
||||||
| hir::ItemImpl(_, _, _, ref generics, ..) => {
|
| hir::ItemImpl(_, _, _, ref generics, ..) => {
|
||||||
index += (generics.lifetimes.len() + generics.ty_params.len()) as u32;
|
index += generics.params.len() as u32;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lifetimes = generics
|
let lifetimes = generics
|
||||||
.lifetimes
|
.lifetimes()
|
||||||
.iter()
|
|
||||||
.map(|def| {
|
.map(|def| {
|
||||||
if self.map.late_bound.contains(&def.lifetime.id) {
|
if self.map.late_bound.contains(&def.lifetime.id) {
|
||||||
Region::late(&self.tcx.hir, def)
|
Region::late(&self.tcx.hir, def)
|
||||||
|
@ -1301,7 +1297,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let next_early_index = index + generics.ty_params.len() as u32;
|
let next_early_index = index + generics.ty_params().count() as u32;
|
||||||
|
|
||||||
let scope = Scope::Binder {
|
let scope = Scope::Binder {
|
||||||
lifetimes,
|
lifetimes,
|
||||||
|
@ -1309,7 +1305,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
s: self.scope,
|
s: self.scope,
|
||||||
};
|
};
|
||||||
self.with(scope, move |old_scope, this| {
|
self.with(scope, move |old_scope, this| {
|
||||||
this.check_lifetime_defs(old_scope, &generics.lifetimes);
|
this.check_lifetime_params(old_scope, &generics.params);
|
||||||
this.hack(walk); // FIXME(#37666) workaround in place of `walk(this)`
|
this.hack(walk); // FIXME(#37666) workaround in place of `walk(this)`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1769,6 +1765,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_generic_param(&mut self, param: &hir::GenericParam) {
|
||||||
|
if let hir::GenericParam::Lifetime(ref lifetime_def) = *param {
|
||||||
|
for l in &lifetime_def.bounds {
|
||||||
|
self.visit_lifetime(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
intravisit::walk_generic_param(self, param);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_poly_trait_ref(
|
fn visit_poly_trait_ref(
|
||||||
&mut self,
|
&mut self,
|
||||||
trait_ref: &hir::PolyTraitRef,
|
trait_ref: &hir::PolyTraitRef,
|
||||||
|
@ -1779,12 +1785,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
self.binder_depth -= 1;
|
self.binder_depth -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_lifetime_def(&mut self, lifetime_def: &hir::LifetimeDef) {
|
|
||||||
for l in &lifetime_def.bounds {
|
|
||||||
self.visit_lifetime(l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
|
fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
|
||||||
if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.id) {
|
if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.id) {
|
||||||
match lifetime {
|
match lifetime {
|
||||||
|
@ -1980,11 +1980,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth));
|
self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_lifetime_defs(&mut self, old_scope: ScopeRef, lifetimes: &'tcx [hir::LifetimeDef]) {
|
fn check_lifetime_params(&mut self, old_scope: ScopeRef, params: &'tcx [hir::GenericParam]) {
|
||||||
for i in 0..lifetimes.len() {
|
for (i, lifetime_i) in params.lifetimes().enumerate() {
|
||||||
let lifetime_i = &lifetimes[i];
|
for lifetime in params.lifetimes() {
|
||||||
|
|
||||||
for lifetime in lifetimes {
|
|
||||||
match lifetime.lifetime.name {
|
match lifetime.lifetime.name {
|
||||||
hir::LifetimeName::Static | hir::LifetimeName::Underscore => {
|
hir::LifetimeName::Static | hir::LifetimeName::Underscore => {
|
||||||
let lifetime = lifetime.lifetime;
|
let lifetime = lifetime.lifetime;
|
||||||
|
@ -2007,9 +2005,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is a hard error to shadow a lifetime within the same scope.
|
// It is a hard error to shadow a lifetime within the same scope.
|
||||||
for j in i + 1..lifetimes.len() {
|
for lifetime_j in params.lifetimes().skip(i + 1) {
|
||||||
let lifetime_j = &lifetimes[j];
|
|
||||||
|
|
||||||
if lifetime_i.lifetime.name == lifetime_j.lifetime.name {
|
if lifetime_i.lifetime.name == lifetime_j.lifetime.name {
|
||||||
struct_span_err!(
|
struct_span_err!(
|
||||||
self.tcx.sess,
|
self.tcx.sess,
|
||||||
|
@ -2200,24 +2196,30 @@ fn insert_late_bound_lifetimes(
|
||||||
let mut appears_in_where_clause = AllCollector {
|
let mut appears_in_where_clause = AllCollector {
|
||||||
regions: FxHashSet(),
|
regions: FxHashSet(),
|
||||||
};
|
};
|
||||||
for ty_param in generics.ty_params.iter() {
|
|
||||||
|
for param in &generics.params {
|
||||||
|
match *param {
|
||||||
|
hir::GenericParam::Lifetime(ref lifetime_def) => {
|
||||||
|
if !lifetime_def.bounds.is_empty() {
|
||||||
|
// `'a: 'b` means both `'a` and `'b` are referenced
|
||||||
|
appears_in_where_clause.visit_generic_param(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hir::GenericParam::Type(ref ty_param) => {
|
||||||
walk_list!(
|
walk_list!(
|
||||||
&mut appears_in_where_clause,
|
&mut appears_in_where_clause,
|
||||||
visit_ty_param_bound,
|
visit_ty_param_bound,
|
||||||
&ty_param.bounds
|
&ty_param.bounds
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
walk_list!(
|
walk_list!(
|
||||||
&mut appears_in_where_clause,
|
&mut appears_in_where_clause,
|
||||||
visit_where_predicate,
|
visit_where_predicate,
|
||||||
&generics.where_clause.predicates
|
&generics.where_clause.predicates
|
||||||
);
|
);
|
||||||
for lifetime_def in &generics.lifetimes {
|
|
||||||
if !lifetime_def.bounds.is_empty() {
|
|
||||||
// `'a: 'b` means both `'a` and `'b` are referenced
|
|
||||||
appears_in_where_clause.visit_lifetime_def(lifetime_def);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"insert_late_bound_lifetimes: appears_in_where_clause={:?}",
|
"insert_late_bound_lifetimes: appears_in_where_clause={:?}",
|
||||||
|
@ -2228,7 +2230,7 @@ fn insert_late_bound_lifetimes(
|
||||||
// - appear in the inputs
|
// - appear in the inputs
|
||||||
// - do not appear in the where-clauses
|
// - do not appear in the where-clauses
|
||||||
// - are not implicitly captured by `impl Trait`
|
// - are not implicitly captured by `impl Trait`
|
||||||
for lifetime in &generics.lifetimes {
|
for lifetime in generics.lifetimes() {
|
||||||
let name = lifetime.lifetime.name;
|
let name = lifetime.lifetime.name;
|
||||||
|
|
||||||
// appears in the where clauses? early-bound.
|
// appears in the where clauses? early-bound.
|
||||||
|
|
|
@ -126,8 +126,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCamelCaseTypes {
|
||||||
self.check_case(cx, "variant", v.node.name, v.span);
|
self.check_case(cx, "variant", v.node.name, v.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_generics(&mut self, cx: &LateContext, it: &hir::Generics) {
|
fn check_generic_param(&mut self, cx: &LateContext, param: &hir::GenericParam) {
|
||||||
for gen in it.ty_params.iter() {
|
if let hir::GenericParam::Type(ref gen) = *param {
|
||||||
self.check_case(cx, "type parameter", gen.name, gen.span);
|
self.check_case(cx, "type parameter", gen.name, gen.span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,6 +232,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_generic_param(&mut self, cx: &LateContext, param: &hir::GenericParam) {
|
||||||
|
if let hir::GenericParam::Lifetime(ref ld) = *param {
|
||||||
|
self.check_snake_case(
|
||||||
|
cx,
|
||||||
|
"lifetime",
|
||||||
|
&ld.lifetime.name.name().as_str(),
|
||||||
|
Some(ld.lifetime.span)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn check_fn(&mut self,
|
fn check_fn(&mut self,
|
||||||
cx: &LateContext,
|
cx: &LateContext,
|
||||||
fk: FnKind,
|
fk: FnKind,
|
||||||
|
@ -280,13 +291,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_lifetime_def(&mut self, cx: &LateContext, t: &hir::LifetimeDef) {
|
|
||||||
self.check_snake_case(cx,
|
|
||||||
"lifetime",
|
|
||||||
&t.lifetime.name.name().as_str(),
|
|
||||||
Some(t.lifetime.span));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
|
fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
|
||||||
if let &PatKind::Binding(_, _, ref path1, _) = &p.node {
|
if let &PatKind::Binding(_, _, ref path1, _) = &p.node {
|
||||||
self.check_snake_case(cx, "variable", &path1.node.as_str(), Some(p.span));
|
self.check_snake_case(cx, "variable", &path1.node.as_str(), Some(p.span));
|
||||||
|
|
|
@ -507,21 +507,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations {
|
||||||
}
|
}
|
||||||
let (def, ty) = match item.node {
|
let (def, ty) = match item.node {
|
||||||
hir::ItemStruct(_, ref ast_generics) => {
|
hir::ItemStruct(_, ref ast_generics) => {
|
||||||
if ast_generics.is_parameterized() {
|
if !ast_generics.params.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let def = cx.tcx.adt_def(cx.tcx.hir.local_def_id(item.id));
|
let def = cx.tcx.adt_def(cx.tcx.hir.local_def_id(item.id));
|
||||||
(def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
|
(def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
|
||||||
}
|
}
|
||||||
hir::ItemUnion(_, ref ast_generics) => {
|
hir::ItemUnion(_, ref ast_generics) => {
|
||||||
if ast_generics.is_parameterized() {
|
if !ast_generics.params.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let def = cx.tcx.adt_def(cx.tcx.hir.local_def_id(item.id));
|
let def = cx.tcx.adt_def(cx.tcx.hir.local_def_id(item.id));
|
||||||
(def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
|
(def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
|
||||||
}
|
}
|
||||||
hir::ItemEnum(_, ref ast_generics) => {
|
hir::ItemEnum(_, ref ast_generics) => {
|
||||||
if ast_generics.is_parameterized() {
|
if !ast_generics.params.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let def = cx.tcx.adt_def(cx.tcx.hir.local_def_id(item.id));
|
let def = cx.tcx.adt_def(cx.tcx.hir.local_def_id(item.id));
|
||||||
|
|
|
@ -744,7 +744,7 @@ impl LintPass for VariantSizeDifferences {
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
|
||||||
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
|
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
|
||||||
if let hir::ItemEnum(ref enum_definition, ref gens) = it.node {
|
if let hir::ItemEnum(ref enum_definition, ref gens) = it.node {
|
||||||
if gens.ty_params.is_empty() {
|
if gens.params.iter().all(|param| param.is_lifetime_param()) {
|
||||||
// sizes only make sense for non-generic types
|
// sizes only make sense for non-generic types
|
||||||
let item_def_id = cx.tcx.hir.local_def_id(it.id);
|
let item_def_id = cx.tcx.hir.local_def_id(it.id);
|
||||||
let t = cx.tcx.type_of(item_def_id);
|
let t = cx.tcx.type_of(item_def_id);
|
||||||
|
|
|
@ -1078,8 +1078,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||||
}
|
}
|
||||||
hir::ItemConst(..) => self.encode_optimized_mir(def_id),
|
hir::ItemConst(..) => self.encode_optimized_mir(def_id),
|
||||||
hir::ItemFn(_, _, constness, _, ref generics, _) => {
|
hir::ItemFn(_, _, constness, _, ref generics, _) => {
|
||||||
let tps_len = generics.ty_params.len();
|
let has_tps = generics.ty_params().next().is_some();
|
||||||
let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs);
|
let needs_inline = has_tps || attr::requests_inline(&item.attrs);
|
||||||
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
|
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
|
||||||
if needs_inline || constness == hir::Constness::Const || always_encode_mir {
|
if needs_inline || constness == hir::Constness::Const || always_encode_mir {
|
||||||
self.encode_optimized_mir(def_id)
|
self.encode_optimized_mir(def_id)
|
||||||
|
@ -1480,7 +1480,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_info_for_generics(&mut self, generics: &hir::Generics) {
|
fn encode_info_for_generics(&mut self, generics: &hir::Generics) {
|
||||||
for ty_param in &generics.ty_params {
|
for ty_param in generics.ty_params() {
|
||||||
let def_id = self.tcx.hir.local_def_id(ty_param.id);
|
let def_id = self.tcx.hir.local_def_id(ty_param.id);
|
||||||
let has_default = Untracked(ty_param.default.is_some());
|
let has_default = Untracked(ty_param.default.is_some());
|
||||||
self.record(def_id, IsolatedEncoder::encode_info_for_ty_param, (def_id, has_default));
|
self.record(def_id, IsolatedEncoder::encode_info_for_ty_param, (def_id, has_default));
|
||||||
|
|
|
@ -922,7 +922,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
|
||||||
hir::ItemEnum(_, ref generics) |
|
hir::ItemEnum(_, ref generics) |
|
||||||
hir::ItemStruct(_, ref generics) |
|
hir::ItemStruct(_, ref generics) |
|
||||||
hir::ItemUnion(_, ref generics) => {
|
hir::ItemUnion(_, ref generics) => {
|
||||||
if !generics.is_parameterized() {
|
if generics.params.is_empty() {
|
||||||
if self.mode == MonoItemCollectionMode::Eager {
|
if self.mode == MonoItemCollectionMode::Eager {
|
||||||
let def_id = self.tcx.hir.local_def_id(item.id);
|
let def_id = self.tcx.hir.local_def_id(item.id);
|
||||||
debug!("RootCollector: ADT drop-glue for {}",
|
debug!("RootCollector: ADT drop-glue for {}",
|
||||||
|
|
|
@ -250,7 +250,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
ItemKind::Trait(is_auto, _, ref generics, ref bounds, ref trait_items) => {
|
ItemKind::Trait(is_auto, _, ref generics, ref bounds, ref trait_items) => {
|
||||||
if is_auto == IsAuto::Yes {
|
if is_auto == IsAuto::Yes {
|
||||||
// Auto traits cannot have generics, super traits nor contain items.
|
// Auto traits cannot have generics, super traits nor contain items.
|
||||||
if !generics.ty_params.is_empty() {
|
if generics.is_parameterized() {
|
||||||
self.err_handler().span_err(item.span,
|
self.err_handler().span_err(item.span,
|
||||||
"auto traits cannot have generics");
|
"auto traits cannot have generics");
|
||||||
}
|
}
|
||||||
|
@ -283,8 +283,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemKind::TraitAlias(Generics { ref ty_params, .. }, ..) => {
|
ItemKind::TraitAlias(Generics { ref params, .. }, ..) => {
|
||||||
for &TyParam { ref bounds, ref default, span, .. } in ty_params {
|
for param in params {
|
||||||
|
if let GenericParam::Type(TyParam {
|
||||||
|
ref bounds,
|
||||||
|
ref default,
|
||||||
|
span,
|
||||||
|
..
|
||||||
|
}) = *param
|
||||||
|
{
|
||||||
if !bounds.is_empty() {
|
if !bounds.is_empty() {
|
||||||
self.err_handler().span_err(span,
|
self.err_handler().span_err(span,
|
||||||
"type parameters on the left side of a \
|
"type parameters on the left side of a \
|
||||||
|
@ -297,6 +304,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ItemKind::Mod(_) => {
|
ItemKind::Mod(_) => {
|
||||||
// Ensure that `path` attributes on modules are recorded as used (c.f. #35584).
|
// Ensure that `path` attributes on modules are recorded as used (c.f. #35584).
|
||||||
attr::first_attr_value_str_by_name(&item.attrs, "path");
|
attr::first_attr_value_str_by_name(&item.attrs, "path");
|
||||||
|
@ -352,9 +360,21 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_generics(&mut self, g: &'a Generics) {
|
fn visit_generics(&mut self, g: &'a Generics) {
|
||||||
|
let mut seen_non_lifetime_param = false;
|
||||||
let mut seen_default = None;
|
let mut seen_default = None;
|
||||||
for ty_param in &g.ty_params {
|
for param in &g.params {
|
||||||
if ty_param.default.is_some() {
|
match (param, seen_non_lifetime_param) {
|
||||||
|
(&GenericParam::Lifetime(ref ld), true) => {
|
||||||
|
self.err_handler()
|
||||||
|
.span_err(ld.lifetime.span, "lifetime parameters must be leading");
|
||||||
|
},
|
||||||
|
(&GenericParam::Lifetime(_), false) => {}
|
||||||
|
_ => {
|
||||||
|
seen_non_lifetime_param = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let GenericParam::Type(ref ty_param @ TyParam { default: Some(_), .. }) = *param {
|
||||||
seen_default = Some(ty_param.span);
|
seen_default = Some(ty_param.span);
|
||||||
} else if let Some(span) = seen_default {
|
} else if let Some(span) = seen_default {
|
||||||
self.err_handler()
|
self.err_handler()
|
||||||
|
|
|
@ -224,10 +224,6 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||||
self.record("Lifetime", Id::Node(lifetime.id), lifetime);
|
self.record("Lifetime", Id::Node(lifetime.id), lifetime);
|
||||||
hir_visit::walk_lifetime(self, lifetime)
|
hir_visit::walk_lifetime(self, lifetime)
|
||||||
}
|
}
|
||||||
fn visit_lifetime_def(&mut self, lifetime: &'v hir::LifetimeDef) {
|
|
||||||
self.record("LifetimeDef", Id::None, lifetime);
|
|
||||||
hir_visit::walk_lifetime_def(self, lifetime)
|
|
||||||
}
|
|
||||||
fn visit_qpath(&mut self, qpath: &'v hir::QPath, id: NodeId, span: Span) {
|
fn visit_qpath(&mut self, qpath: &'v hir::QPath, id: NodeId, span: Span) {
|
||||||
self.record("QPath", Id::None, qpath);
|
self.record("QPath", Id::None, qpath);
|
||||||
hir_visit::walk_qpath(self, qpath, id, span)
|
hir_visit::walk_qpath(self, qpath, id, span)
|
||||||
|
@ -349,11 +345,6 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
|
||||||
ast_visit::walk_lifetime(self, lifetime)
|
ast_visit::walk_lifetime(self, lifetime)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_lifetime_def(&mut self, lifetime: &'v ast::LifetimeDef) {
|
|
||||||
self.record("LifetimeDef", Id::None, lifetime);
|
|
||||||
ast_visit::walk_lifetime_def(self, lifetime)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_mac(&mut self, mac: &'v ast::Mac) {
|
fn visit_mac(&mut self, mac: &'v ast::Mac) {
|
||||||
self.record("Mac", Id::None, mac);
|
self.record("Mac", Id::None, mac);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1236,7 +1236,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
||||||
for ty_param in generics.ty_params.iter() {
|
for ty_param in generics.ty_params() {
|
||||||
for bound in ty_param.bounds.iter() {
|
for bound in ty_param.bounds.iter() {
|
||||||
self.check_ty_param_bound(bound)
|
self.check_ty_param_bound(bound)
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ use syntax::util::lev_distance::find_best_match_for_name;
|
||||||
use syntax::visit::{self, FnKind, Visitor};
|
use syntax::visit::{self, FnKind, Visitor};
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::ast::{Arm, BindingMode, Block, Crate, Expr, ExprKind};
|
use syntax::ast::{Arm, BindingMode, Block, Crate, Expr, ExprKind};
|
||||||
use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, Generics};
|
use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, GenericParam, Generics};
|
||||||
use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
|
use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
|
||||||
use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
|
use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
|
||||||
use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
|
use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
|
||||||
|
@ -790,25 +790,30 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
||||||
// to following type parameters, as the Substs can only
|
// to following type parameters, as the Substs can only
|
||||||
// provide previous type parameters as they're built.
|
// provide previous type parameters as they're built.
|
||||||
let mut default_ban_rib = Rib::new(ForwardTyParamBanRibKind);
|
let mut default_ban_rib = Rib::new(ForwardTyParamBanRibKind);
|
||||||
default_ban_rib.bindings.extend(generics.ty_params.iter()
|
default_ban_rib.bindings.extend(generics.params.iter()
|
||||||
|
.filter_map(|p| if let GenericParam::Type(ref tp) = *p { Some(tp) } else { None })
|
||||||
.skip_while(|p| p.default.is_none())
|
.skip_while(|p| p.default.is_none())
|
||||||
.map(|p| (Ident::with_empty_ctxt(p.ident.name), Def::Err)));
|
.map(|p| (Ident::with_empty_ctxt(p.ident.name), Def::Err)));
|
||||||
|
|
||||||
for param in &generics.ty_params {
|
for param in &generics.params {
|
||||||
for bound in ¶m.bounds {
|
match *param {
|
||||||
|
GenericParam::Lifetime(_) => self.visit_generic_param(param),
|
||||||
|
GenericParam::Type(ref ty_param) => {
|
||||||
|
for bound in &ty_param.bounds {
|
||||||
self.visit_ty_param_bound(bound);
|
self.visit_ty_param_bound(bound);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref ty) = param.default {
|
if let Some(ref ty) = ty_param.default {
|
||||||
self.ribs[TypeNS].push(default_ban_rib);
|
self.ribs[TypeNS].push(default_ban_rib);
|
||||||
self.visit_ty(ty);
|
self.visit_ty(ty);
|
||||||
default_ban_rib = self.ribs[TypeNS].pop().unwrap();
|
default_ban_rib = self.ribs[TypeNS].pop().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow all following defaults to refer to this type parameter.
|
// Allow all following defaults to refer to this type parameter.
|
||||||
default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(param.ident.name));
|
default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(ty_param.ident.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for lt in &generics.lifetimes { self.visit_lifetime_def(lt); }
|
|
||||||
for p in &generics.where_clause.predicates { self.visit_where_predicate(p); }
|
for p in &generics.where_clause.predicates { self.visit_where_predicate(p); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2022,14 +2027,17 @@ impl<'a> Resolver<'a> {
|
||||||
HasTypeParameters(generics, rib_kind) => {
|
HasTypeParameters(generics, rib_kind) => {
|
||||||
let mut function_type_rib = Rib::new(rib_kind);
|
let mut function_type_rib = Rib::new(rib_kind);
|
||||||
let mut seen_bindings = FxHashMap();
|
let mut seen_bindings = FxHashMap();
|
||||||
for type_parameter in &generics.ty_params {
|
for param in &generics.params {
|
||||||
|
if let GenericParam::Type(ref type_parameter) = *param {
|
||||||
let ident = type_parameter.ident.modern();
|
let ident = type_parameter.ident.modern();
|
||||||
debug!("with_type_parameter_rib: {}", type_parameter.id);
|
debug!("with_type_parameter_rib: {}", type_parameter.id);
|
||||||
|
|
||||||
if seen_bindings.contains_key(&ident) {
|
if seen_bindings.contains_key(&ident) {
|
||||||
let span = seen_bindings.get(&ident).unwrap();
|
let span = seen_bindings.get(&ident).unwrap();
|
||||||
let err =
|
let err = ResolutionError::NameAlreadyUsedInTypeParameterList(
|
||||||
ResolutionError::NameAlreadyUsedInTypeParameterList(ident.name, span);
|
ident.name,
|
||||||
|
span,
|
||||||
|
);
|
||||||
resolve_error(self, type_parameter.span, err);
|
resolve_error(self, type_parameter.span, err);
|
||||||
}
|
}
|
||||||
seen_bindings.entry(ident).or_insert(type_parameter.span);
|
seen_bindings.entry(ident).or_insert(type_parameter.span);
|
||||||
|
@ -2040,6 +2048,7 @@ impl<'a> Resolver<'a> {
|
||||||
function_type_rib.bindings.insert(ident, def);
|
function_type_rib.bindings.insert(ident, def);
|
||||||
self.record_def(type_parameter.id, PathResolution::new(def));
|
self.record_def(type_parameter.id, PathResolution::new(def));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
self.ribs[TypeNS].push(function_type_rib);
|
self.ribs[TypeNS].push(function_type_rib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,12 @@ use syntax::ast::{self, Attribute, NodeId, PatKind, CRATE_NODE_ID};
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::symbol::keywords;
|
use syntax::symbol::keywords;
|
||||||
use syntax::visit::{self, Visitor};
|
use syntax::visit::{self, Visitor};
|
||||||
use syntax::print::pprust::{bounds_to_string, generics_to_string, path_to_string, ty_to_string};
|
use syntax::print::pprust::{
|
||||||
|
bounds_to_string,
|
||||||
|
generic_params_to_string,
|
||||||
|
path_to_string,
|
||||||
|
ty_to_string
|
||||||
|
};
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax::codemap::{Spanned, DUMMY_SP};
|
use syntax::codemap::{Spanned, DUMMY_SP};
|
||||||
use syntax_pos::*;
|
use syntax_pos::*;
|
||||||
|
@ -438,13 +443,14 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||||
prefix: &str,
|
prefix: &str,
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
) {
|
) {
|
||||||
for param in &generics.ty_params {
|
for param in &generics.params {
|
||||||
let param_ss = param.span;
|
if let ast::GenericParam::Type(ref ty_param) = *param {
|
||||||
|
let param_ss = ty_param.span;
|
||||||
let name = escape(self.span.snippet(param_ss));
|
let name = escape(self.span.snippet(param_ss));
|
||||||
// Append $id to name to make sure each one is unique
|
// Append $id to name to make sure each one is unique
|
||||||
let qualname = format!("{}::{}${}", prefix, name, id);
|
let qualname = format!("{}::{}${}", prefix, name, id);
|
||||||
if !self.span.filter_generated(Some(param_ss), full_span) {
|
if !self.span.filter_generated(Some(param_ss), full_span) {
|
||||||
let id = ::id_from_node_id(param.id, &self.save_ctxt);
|
let id = ::id_from_node_id(ty_param.id, &self.save_ctxt);
|
||||||
let span = self.span_from_span(param_ss);
|
let span = self.span_from_span(param_ss);
|
||||||
|
|
||||||
self.dumper.dump_def(
|
self.dumper.dump_def(
|
||||||
|
@ -469,6 +475,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
self.visit_generics(generics);
|
self.visit_generics(generics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -787,8 +794,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||||
let name = item.ident.to_string();
|
let name = item.ident.to_string();
|
||||||
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
|
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
|
||||||
let mut val = name.clone();
|
let mut val = name.clone();
|
||||||
if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() {
|
if !generics.params.is_empty() {
|
||||||
val.push_str(&generics_to_string(generics));
|
val.push_str(&generic_params_to_string(&generics.params));
|
||||||
}
|
}
|
||||||
if !trait_refs.is_empty() {
|
if !trait_refs.is_empty() {
|
||||||
val.push_str(": ");
|
val.push_str(": ");
|
||||||
|
@ -1478,17 +1485,19 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_generics(&mut self, generics: &'l ast::Generics) {
|
fn visit_generics(&mut self, generics: &'l ast::Generics) {
|
||||||
for param in generics.ty_params.iter() {
|
for param in &generics.params {
|
||||||
for bound in param.bounds.iter() {
|
if let ast::GenericParam::Type(ref ty_param) = *param {
|
||||||
|
for bound in ty_param.bounds.iter() {
|
||||||
if let ast::TraitTyParamBound(ref trait_ref, _) = *bound {
|
if let ast::TraitTyParamBound(ref trait_ref, _) = *bound {
|
||||||
self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
|
self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(ref ty) = param.default {
|
if let Some(ref ty) = ty_param.default {
|
||||||
self.visit_ty(&ty);
|
self.visit_ty(&ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: &'l ast::Ty) {
|
fn visit_ty(&mut self, t: &'l ast::Ty) {
|
||||||
self.process_macro_use(t.span);
|
self.process_macro_use(t.span);
|
||||||
|
|
|
@ -886,21 +886,15 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||||
|
|
||||||
fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String {
|
fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String {
|
||||||
let mut sig = "fn ".to_owned();
|
let mut sig = "fn ".to_owned();
|
||||||
if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() {
|
if !generics.params.is_empty() {
|
||||||
sig.push('<');
|
sig.push('<');
|
||||||
sig.push_str(&generics
|
sig.push_str(&generics
|
||||||
.lifetimes
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|l| l.lifetime.ident.name.to_string())
|
.map(|param| match *param {
|
||||||
.collect::<Vec<_>>()
|
ast::GenericParam::Lifetime(ref l) => l.lifetime.ident.name.to_string(),
|
||||||
.join(", "));
|
ast::GenericParam::Type(ref t) => t.ident.to_string(),
|
||||||
if !generics.lifetimes.is_empty() {
|
})
|
||||||
sig.push_str(", ");
|
|
||||||
}
|
|
||||||
sig.push_str(&generics
|
|
||||||
.ty_params
|
|
||||||
.iter()
|
|
||||||
.map(|l| l.ident.to_string())
|
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", "));
|
.join(", "));
|
||||||
sig.push_str("> ");
|
sig.push_str("> ");
|
||||||
|
|
|
@ -218,12 +218,17 @@ impl Sig for ast::Ty {
|
||||||
}
|
}
|
||||||
ast::TyKind::BareFn(ref f) => {
|
ast::TyKind::BareFn(ref f) => {
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
if !f.lifetimes.is_empty() {
|
if !f.generic_params.is_empty() {
|
||||||
// FIXME defs, bounds on lifetimes
|
// FIXME defs, bounds on lifetimes
|
||||||
text.push_str("for<");
|
text.push_str("for<");
|
||||||
text.push_str(&f.lifetimes
|
text.push_str(&f.generic_params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|l| l.lifetime.ident.to_string())
|
.filter_map(|p| match *p {
|
||||||
|
ast::GenericParam::Lifetime(ref l) => {
|
||||||
|
Some(l.lifetime.ident.to_string())
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", "));
|
.join(", "));
|
||||||
text.push('>');
|
text.push('>');
|
||||||
|
@ -615,15 +620,16 @@ impl Sig for ast::Path {
|
||||||
// This does not cover the where clause, which must be processed separately.
|
// This does not cover the where clause, which must be processed separately.
|
||||||
impl Sig for ast::Generics {
|
impl Sig for ast::Generics {
|
||||||
fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) -> Result {
|
fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) -> Result {
|
||||||
let total = self.lifetimes.len() + self.ty_params.len();
|
if self.params.is_empty() {
|
||||||
if total == 0 {
|
|
||||||
return Ok(text_sig(String::new()));
|
return Ok(text_sig(String::new()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut text = "<".to_owned();
|
let mut text = "<".to_owned();
|
||||||
|
|
||||||
let mut defs = vec![];
|
let mut defs = vec![];
|
||||||
for l in &self.lifetimes {
|
for param in &self.params {
|
||||||
|
match *param {
|
||||||
|
ast::GenericParam::Lifetime(ref l) => {
|
||||||
let mut l_text = l.lifetime.ident.to_string();
|
let mut l_text = l.lifetime.ident.to_string();
|
||||||
defs.push(SigElement {
|
defs.push(SigElement {
|
||||||
id: id_from_node_id(l.lifetime.id, scx),
|
id: id_from_node_id(l.lifetime.id, scx),
|
||||||
|
@ -644,7 +650,7 @@ impl Sig for ast::Generics {
|
||||||
text.push_str(&l_text);
|
text.push_str(&l_text);
|
||||||
text.push(',');
|
text.push(',');
|
||||||
}
|
}
|
||||||
for t in &self.ty_params {
|
ast::GenericParam::Type(ref t) => {
|
||||||
let mut t_text = t.ident.to_string();
|
let mut t_text = t.ident.to_string();
|
||||||
defs.push(SigElement {
|
defs.push(SigElement {
|
||||||
id: id_from_node_id(t.id, scx),
|
id: id_from_node_id(t.id, scx),
|
||||||
|
@ -660,6 +666,8 @@ impl Sig for ast::Generics {
|
||||||
text.push_str(&t_text);
|
text.push_str(&t_text);
|
||||||
text.push(',');
|
text.push(',');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
text.push('>');
|
text.push('>');
|
||||||
Ok(Signature {
|
Ok(Signature {
|
||||||
|
|
|
@ -562,10 +562,10 @@ fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
if num_impl_m_type_params != num_trait_m_type_params {
|
if num_impl_m_type_params != num_trait_m_type_params {
|
||||||
let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
|
let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
|
||||||
let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id);
|
let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id);
|
||||||
let span = if impl_m_item.generics.is_parameterized() {
|
let span = if impl_m_item.generics.params.is_empty() {
|
||||||
impl_m_item.generics.span
|
|
||||||
} else {
|
|
||||||
impl_m_span
|
impl_m_span
|
||||||
|
} else {
|
||||||
|
impl_m_item.generics.span
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut err = struct_span_err!(tcx.sess,
|
let mut err = struct_span_err!(tcx.sess,
|
||||||
|
|
|
@ -4949,16 +4949,18 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
generics: &hir::Generics,
|
generics: &hir::Generics,
|
||||||
ty: Ty<'tcx>) {
|
ty: Ty<'tcx>) {
|
||||||
debug!("check_bounds_are_used(n_tps={}, ty={:?})",
|
debug!("check_bounds_are_used(n_tps={}, ty={:?})",
|
||||||
generics.ty_params.len(), ty);
|
generics.ty_params().count(), ty);
|
||||||
|
|
||||||
// make a vector of booleans initially false, set to true when used
|
// make a vector of booleans initially false, set to true when used
|
||||||
if generics.ty_params.is_empty() { return; }
|
if generics.ty_params().next().is_none() { return; }
|
||||||
let mut tps_used = vec![false; generics.ty_params.len()];
|
let mut tps_used = vec![false; generics.ty_params().count()];
|
||||||
|
|
||||||
|
let lifetime_count = generics.lifetimes().count();
|
||||||
|
|
||||||
for leaf_ty in ty.walk() {
|
for leaf_ty in ty.walk() {
|
||||||
if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
|
if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty {
|
||||||
debug!("Found use of ty param num {}", idx);
|
debug!("Found use of ty param num {}", idx);
|
||||||
tps_used[idx as usize - generics.lifetimes.len()] = true;
|
tps_used[idx as usize - lifetime_count] = true;
|
||||||
} else if let ty::TyError = leaf_ty.sty {
|
} else if let ty::TyError = leaf_ty.sty {
|
||||||
// If there already another error, do not emit an error for not using a type Parameter
|
// If there already another error, do not emit an error for not using a type Parameter
|
||||||
assert!(tcx.sess.err_count() > 0);
|
assert!(tcx.sess.err_count() > 0);
|
||||||
|
@ -4966,7 +4968,7 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (&used, param) in tps_used.iter().zip(&generics.ty_params) {
|
for (&used, param) in tps_used.iter().zip(generics.ty_params()) {
|
||||||
if !used {
|
if !used {
|
||||||
struct_span_err!(tcx.sess, param.span, E0091,
|
struct_span_err!(tcx.sess, param.span, E0091,
|
||||||
"type parameter `{}` is unused",
|
"type parameter `{}` is unused",
|
||||||
|
|
|
@ -592,13 +592,9 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (span, name) = if index < ast_generics.lifetimes.len() {
|
let (span, name) = match ast_generics.params[index] {
|
||||||
(ast_generics.lifetimes[index].lifetime.span,
|
hir::GenericParam::Lifetime(ref ld) => (ld.lifetime.span, ld.lifetime.name.name()),
|
||||||
ast_generics.lifetimes[index].lifetime.name.name())
|
hir::GenericParam::Type(ref tp) => (tp.span, tp.name),
|
||||||
} else {
|
|
||||||
let index = index - ast_generics.lifetimes.len();
|
|
||||||
(ast_generics.ty_params[index].span,
|
|
||||||
ast_generics.ty_params[index].name)
|
|
||||||
};
|
};
|
||||||
self.report_bivariance(span, name);
|
self.report_bivariance(span, name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
||||||
for param in &generics.ty_params {
|
for param in generics.ty_params() {
|
||||||
if param.default.is_some() {
|
if param.default.is_some() {
|
||||||
let def_id = self.tcx.hir.local_def_id(param.id);
|
let def_id = self.tcx.hir.local_def_id(param.id);
|
||||||
self.tcx.type_of(def_id);
|
self.tcx.type_of(def_id);
|
||||||
|
@ -315,8 +315,7 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
|
||||||
-> Vec<ty::Predicate<'tcx>>
|
-> Vec<ty::Predicate<'tcx>>
|
||||||
{
|
{
|
||||||
let from_ty_params =
|
let from_ty_params =
|
||||||
ast_generics.ty_params
|
ast_generics.ty_params()
|
||||||
.iter()
|
|
||||||
.filter(|p| p.id == param_id)
|
.filter(|p| p.id == param_id)
|
||||||
.flat_map(|p| p.bounds.iter())
|
.flat_map(|p| p.bounds.iter())
|
||||||
.flat_map(|b| predicates_from_bound(self, ty, b));
|
.flat_map(|b| predicates_from_bound(self, ty, b));
|
||||||
|
@ -365,7 +364,7 @@ fn ensure_no_ty_param_bounds(tcx: TyCtxt,
|
||||||
thing: &'static str) {
|
thing: &'static str) {
|
||||||
let mut warn = false;
|
let mut warn = false;
|
||||||
|
|
||||||
for ty_param in generics.ty_params.iter() {
|
for ty_param in generics.ty_params() {
|
||||||
for bound in ty_param.bounds.iter() {
|
for bound in ty_param.bounds.iter() {
|
||||||
match *bound {
|
match *bound {
|
||||||
hir::TraitTyParamBound(..) => {
|
hir::TraitTyParamBound(..) => {
|
||||||
|
@ -804,7 +803,7 @@ fn has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
let mut visitor = LateBoundRegionsDetector {
|
let mut visitor = LateBoundRegionsDetector {
|
||||||
tcx, binder_depth: 1, has_late_bound_regions: None
|
tcx, binder_depth: 1, has_late_bound_regions: None
|
||||||
};
|
};
|
||||||
for lifetime in &generics.lifetimes {
|
for lifetime in generics.lifetimes() {
|
||||||
let hir_id = tcx.hir.node_to_hir_id(lifetime.lifetime.id);
|
let hir_id = tcx.hir.node_to_hir_id(lifetime.lifetime.id);
|
||||||
if tcx.is_late_bound(hir_id) {
|
if tcx.is_late_bound(hir_id) {
|
||||||
return Some(lifetime.lifetime.span);
|
return Some(lifetime.lifetime.span);
|
||||||
|
@ -964,7 +963,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
|
||||||
// Now create the real type parameters.
|
// Now create the real type parameters.
|
||||||
let type_start = own_start + regions.len() as u32;
|
let type_start = own_start + regions.len() as u32;
|
||||||
let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
|
let types = ast_generics.ty_params().enumerate().map(|(i, p)| {
|
||||||
if p.name == keywords::SelfType.name() {
|
if p.name == keywords::SelfType.name() {
|
||||||
span_bug!(p.span, "`Self` should not be the name of a regular parameter");
|
span_bug!(p.span, "`Self` should not be the name of a regular parameter");
|
||||||
}
|
}
|
||||||
|
@ -1359,8 +1358,7 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>(
|
||||||
-> impl Iterator<Item=&'a hir::LifetimeDef>
|
-> impl Iterator<Item=&'a hir::LifetimeDef>
|
||||||
{
|
{
|
||||||
ast_generics
|
ast_generics
|
||||||
.lifetimes
|
.lifetimes()
|
||||||
.iter()
|
|
||||||
.filter(move |l| {
|
.filter(move |l| {
|
||||||
let hir_id = tcx.hir.node_to_hir_id(l.lifetime.id);
|
let hir_id = tcx.hir.node_to_hir_id(l.lifetime.id);
|
||||||
!tcx.is_late_bound(hir_id)
|
!tcx.is_late_bound(hir_id)
|
||||||
|
@ -1492,7 +1490,7 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
|
||||||
// Collect the predicates that were written inline by the user on each
|
// Collect the predicates that were written inline by the user on each
|
||||||
// type parameter (e.g., `<T:Foo>`).
|
// type parameter (e.g., `<T:Foo>`).
|
||||||
for param in &ast_generics.ty_params {
|
for param in ast_generics.ty_params() {
|
||||||
let param_ty = ty::ParamTy::new(index, param.name).to_ty(tcx);
|
let param_ty = ty::ParamTy::new(index, param.name).to_ty(tcx);
|
||||||
index += 1;
|
index += 1;
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
tcx, &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters);
|
tcx, &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters);
|
||||||
|
|
||||||
// Disallow ANY unconstrained type parameters.
|
// Disallow ANY unconstrained type parameters.
|
||||||
for (ty_param, param) in impl_generics.types.iter().zip(&impl_hir_generics.ty_params) {
|
for (ty_param, param) in impl_generics.types.iter().zip(impl_hir_generics.ty_params()) {
|
||||||
let param_ty = ty::ParamTy::for_def(ty_param);
|
let param_ty = ty::ParamTy::for_def(ty_param);
|
||||||
if !input_parameters.contains(&ctp::Parameter::from(param_ty)) {
|
if !input_parameters.contains(&ctp::Parameter::from(param_ty)) {
|
||||||
report_unused_parameter(tcx, param.span, "type", ¶m_ty.to_string());
|
report_unused_parameter(tcx, param.span, "type", ¶m_ty.to_string());
|
||||||
|
@ -123,7 +123,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
ctp::parameters_for(&tcx.type_of(def_id), true)
|
ctp::parameters_for(&tcx.type_of(def_id), true)
|
||||||
}).collect();
|
}).collect();
|
||||||
for (ty_lifetime, lifetime) in impl_generics.regions.iter()
|
for (ty_lifetime, lifetime) in impl_generics.regions.iter()
|
||||||
.zip(&impl_hir_generics.lifetimes)
|
.zip(impl_hir_generics.lifetimes())
|
||||||
{
|
{
|
||||||
let param = ctp::Parameter::from(ty_lifetime.to_early_bound_region_data());
|
let param = ctp::Parameter::from(ty_lifetime.to_early_bound_region_data());
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
Some(hir_map::NodeItem(it)) => {
|
Some(hir_map::NodeItem(it)) => {
|
||||||
match it.node {
|
match it.node {
|
||||||
hir::ItemFn(.., ref generics, _) => {
|
hir::ItemFn(.., ref generics, _) => {
|
||||||
if generics.is_parameterized() {
|
if !generics.params.is_empty() {
|
||||||
struct_span_err!(tcx.sess, generics.span, E0131,
|
struct_span_err!(tcx.sess, generics.span, E0131,
|
||||||
"main function is not allowed to have type parameters")
|
"main function is not allowed to have type parameters")
|
||||||
.span_label(generics.span,
|
.span_label(generics.span,
|
||||||
|
@ -235,7 +235,7 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
Some(hir_map::NodeItem(it)) => {
|
Some(hir_map::NodeItem(it)) => {
|
||||||
match it.node {
|
match it.node {
|
||||||
hir::ItemFn(..,ref ps,_)
|
hir::ItemFn(..,ref ps,_)
|
||||||
if ps.is_parameterized() => {
|
if !ps.params.is_empty() => {
|
||||||
struct_span_err!(tcx.sess, ps.span, E0132,
|
struct_span_err!(tcx.sess, ps.span, E0132,
|
||||||
"start function is not allowed to have type parameters")
|
"start function is not allowed to have type parameters")
|
||||||
.span_label(ps.span,
|
.span_label(ps.span,
|
||||||
|
|
|
@ -43,6 +43,7 @@ use rustc_typeck::hir_ty_to_ty;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
|
|
||||||
use rustc_const_math::ConstInt;
|
use rustc_const_math::ConstInt;
|
||||||
|
use std::default::Default;
|
||||||
use std::{mem, slice, vec};
|
use std::{mem, slice, vec};
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -856,7 +857,7 @@ impl TyParamBound {
|
||||||
did,
|
did,
|
||||||
is_generic: false,
|
is_generic: false,
|
||||||
},
|
},
|
||||||
lifetimes: vec![]
|
generic_params: Vec::new(),
|
||||||
}, hir::TraitBoundModifier::Maybe)
|
}, hir::TraitBoundModifier::Maybe)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -951,7 +952,7 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
|
||||||
if let &ty::RegionKind::ReLateBound(..) = *reg {
|
if let &ty::RegionKind::ReLateBound(..) = *reg {
|
||||||
debug!(" hit an ReLateBound {:?}", reg);
|
debug!(" hit an ReLateBound {:?}", reg);
|
||||||
if let Some(lt) = reg.clean(cx) {
|
if let Some(lt) = reg.clean(cx) {
|
||||||
late_bounds.push(lt);
|
late_bounds.push(GenericParam::Lifetime(lt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -967,7 +968,7 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
|
||||||
did: self.def_id,
|
did: self.def_id,
|
||||||
is_generic: false,
|
is_generic: false,
|
||||||
},
|
},
|
||||||
lifetimes: late_bounds,
|
generic_params: late_bounds,
|
||||||
},
|
},
|
||||||
hir::TraitBoundModifier::None
|
hir::TraitBoundModifier::None
|
||||||
)
|
)
|
||||||
|
@ -981,7 +982,7 @@ impl<'tcx> Clean<Option<Vec<TyParamBound>>> for Substs<'tcx> {
|
||||||
.map(RegionBound));
|
.map(RegionBound));
|
||||||
v.extend(self.types().map(|t| TraitBound(PolyTrait {
|
v.extend(self.types().map(|t| TraitBound(PolyTrait {
|
||||||
trait_: t.clean(cx),
|
trait_: t.clean(cx),
|
||||||
lifetimes: vec![]
|
generic_params: Vec::new(),
|
||||||
}, hir::TraitBoundModifier::None)));
|
}, hir::TraitBoundModifier::None)));
|
||||||
if !v.is_empty() {Some(v)} else {None}
|
if !v.is_empty() {Some(v)} else {None}
|
||||||
}
|
}
|
||||||
|
@ -1186,19 +1187,31 @@ impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// maybe use a Generic enum and use Vec<Generic>?
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
||||||
|
pub enum GenericParam {
|
||||||
|
Lifetime(Lifetime),
|
||||||
|
Type(TyParam),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clean<GenericParam> for hir::GenericParam {
|
||||||
|
fn clean(&self, cx: &DocContext) -> GenericParam {
|
||||||
|
match *self {
|
||||||
|
hir::GenericParam::Lifetime(ref l) => GenericParam::Lifetime(l.clean(cx)),
|
||||||
|
hir::GenericParam::Type(ref t) => GenericParam::Type(t.clean(cx)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug, Default)]
|
||||||
pub struct Generics {
|
pub struct Generics {
|
||||||
pub lifetimes: Vec<Lifetime>,
|
pub params: Vec<GenericParam>,
|
||||||
pub type_params: Vec<TyParam>,
|
|
||||||
pub where_predicates: Vec<WherePredicate>,
|
pub where_predicates: Vec<WherePredicate>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clean<Generics> for hir::Generics {
|
impl Clean<Generics> for hir::Generics {
|
||||||
fn clean(&self, cx: &DocContext) -> Generics {
|
fn clean(&self, cx: &DocContext) -> Generics {
|
||||||
let mut g = Generics {
|
let mut g = Generics {
|
||||||
lifetimes: self.lifetimes.clean(cx),
|
params: self.params.clean(cx),
|
||||||
type_params: self.ty_params.clean(cx),
|
|
||||||
where_predicates: self.where_clause.predicates.clean(cx)
|
where_predicates: self.where_clause.predicates.clean(cx)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1209,14 +1222,16 @@ impl Clean<Generics> for hir::Generics {
|
||||||
match *where_pred {
|
match *where_pred {
|
||||||
WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => {
|
WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => {
|
||||||
if bounds.is_empty() {
|
if bounds.is_empty() {
|
||||||
for type_params in &mut g.type_params {
|
for param in &mut g.params {
|
||||||
if &type_params.name == name {
|
if let GenericParam::Type(ref mut type_param) = *param {
|
||||||
mem::swap(bounds, &mut type_params.bounds);
|
if &type_param.name == name {
|
||||||
|
mem::swap(bounds, &mut type_param.bounds);
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
_ => continue,
|
_ => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1283,8 +1298,16 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
|
||||||
// and instead see `where T: Foo + Bar + Sized + 'a`
|
// and instead see `where T: Foo + Bar + Sized + 'a`
|
||||||
|
|
||||||
Generics {
|
Generics {
|
||||||
type_params: simplify::ty_params(stripped_typarams),
|
params: gens.regions
|
||||||
lifetimes: gens.regions.clean(cx),
|
.clean(cx)
|
||||||
|
.into_iter()
|
||||||
|
.map(|lp| GenericParam::Lifetime(lp))
|
||||||
|
.chain(
|
||||||
|
simplify::ty_params(stripped_typarams)
|
||||||
|
.into_iter()
|
||||||
|
.map(|tp| GenericParam::Type(tp))
|
||||||
|
)
|
||||||
|
.collect(),
|
||||||
where_predicates: simplify::where_clauses(cx, where_predicates),
|
where_predicates: simplify::where_clauses(cx, where_predicates),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1538,7 +1561,7 @@ impl Clean<PolyTrait> for hir::PolyTraitRef {
|
||||||
fn clean(&self, cx: &DocContext) -> PolyTrait {
|
fn clean(&self, cx: &DocContext) -> PolyTrait {
|
||||||
PolyTrait {
|
PolyTrait {
|
||||||
trait_: self.trait_ref.clean(cx),
|
trait_: self.trait_ref.clean(cx),
|
||||||
lifetimes: self.bound_lifetimes.clean(cx)
|
generic_params: self.bound_generic_params.clean(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1590,11 +1613,7 @@ impl Clean<Item> for hir::ImplItem {
|
||||||
}
|
}
|
||||||
hir::ImplItemKind::Type(ref ty) => TypedefItem(Typedef {
|
hir::ImplItemKind::Type(ref ty) => TypedefItem(Typedef {
|
||||||
type_: ty.clean(cx),
|
type_: ty.clean(cx),
|
||||||
generics: Generics {
|
generics: Generics::default(),
|
||||||
lifetimes: Vec::new(),
|
|
||||||
type_params: Vec::new(),
|
|
||||||
where_predicates: Vec::new()
|
|
||||||
},
|
|
||||||
}, true),
|
}, true),
|
||||||
};
|
};
|
||||||
Item {
|
Item {
|
||||||
|
@ -1726,8 +1745,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
|
||||||
TypedefItem(Typedef {
|
TypedefItem(Typedef {
|
||||||
type_: cx.tcx.type_of(self.def_id).clean(cx),
|
type_: cx.tcx.type_of(self.def_id).clean(cx),
|
||||||
generics: Generics {
|
generics: Generics {
|
||||||
lifetimes: Vec::new(),
|
params: Vec::new(),
|
||||||
type_params: Vec::new(),
|
|
||||||
where_predicates: Vec::new(),
|
where_predicates: Vec::new(),
|
||||||
},
|
},
|
||||||
}, true)
|
}, true)
|
||||||
|
@ -1757,7 +1775,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
||||||
pub struct PolyTrait {
|
pub struct PolyTrait {
|
||||||
pub trait_: Type,
|
pub trait_: Type,
|
||||||
pub lifetimes: Vec<Lifetime>
|
pub generic_params: Vec<GenericParam>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original
|
/// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original
|
||||||
|
@ -2081,7 +2099,7 @@ impl Clean<Type> for hir::Ty {
|
||||||
let mut ty_substs = FxHashMap();
|
let mut ty_substs = FxHashMap();
|
||||||
let mut lt_substs = FxHashMap();
|
let mut lt_substs = FxHashMap();
|
||||||
provided_params.with_parameters(|provided_params| {
|
provided_params.with_parameters(|provided_params| {
|
||||||
for (i, ty_param) in generics.ty_params.iter().enumerate() {
|
for (i, ty_param) in generics.ty_params().enumerate() {
|
||||||
let ty_param_def = Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id));
|
let ty_param_def = Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id));
|
||||||
if let Some(ty) = provided_params.types.get(i).cloned() {
|
if let Some(ty) = provided_params.types.get(i).cloned() {
|
||||||
ty_substs.insert(ty_param_def, ty.into_inner().clean(cx));
|
ty_substs.insert(ty_param_def, ty.into_inner().clean(cx));
|
||||||
|
@ -2089,7 +2107,8 @@ impl Clean<Type> for hir::Ty {
|
||||||
ty_substs.insert(ty_param_def, default.into_inner().clean(cx));
|
ty_substs.insert(ty_param_def, default.into_inner().clean(cx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i, lt_param) in generics.lifetimes.iter().enumerate() {
|
|
||||||
|
for (i, lt_param) in generics.lifetimes().enumerate() {
|
||||||
if let Some(lt) = provided_params.lifetimes.get(i).cloned() {
|
if let Some(lt) = provided_params.lifetimes.get(i).cloned() {
|
||||||
if !lt.is_elided() {
|
if !lt.is_elided() {
|
||||||
let lt_def_id = cx.tcx.hir.local_def_id(lt_param.lifetime.id);
|
let lt_def_id = cx.tcx.hir.local_def_id(lt_param.lifetime.id);
|
||||||
|
@ -2197,11 +2216,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||||
let sig = ty.fn_sig(cx.tcx);
|
let sig = ty.fn_sig(cx.tcx);
|
||||||
BareFunction(box BareFunctionDecl {
|
BareFunction(box BareFunctionDecl {
|
||||||
unsafety: sig.unsafety(),
|
unsafety: sig.unsafety(),
|
||||||
generics: Generics {
|
generic_params: Vec::new(),
|
||||||
lifetimes: Vec::new(),
|
|
||||||
type_params: Vec::new(),
|
|
||||||
where_predicates: Vec::new()
|
|
||||||
},
|
|
||||||
decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), sig).clean(cx),
|
decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), sig).clean(cx),
|
||||||
abi: sig.abi(),
|
abi: sig.abi(),
|
||||||
})
|
})
|
||||||
|
@ -2253,7 +2268,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||||
did,
|
did,
|
||||||
is_generic: false,
|
is_generic: false,
|
||||||
},
|
},
|
||||||
lifetimes: vec![]
|
generic_params: Vec::new(),
|
||||||
}, hir::TraitBoundModifier::None);
|
}, hir::TraitBoundModifier::None);
|
||||||
typarams.push(bound);
|
typarams.push(bound);
|
||||||
}
|
}
|
||||||
|
@ -2713,7 +2728,7 @@ impl Clean<Item> for doctree::Typedef {
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
||||||
pub struct BareFunctionDecl {
|
pub struct BareFunctionDecl {
|
||||||
pub unsafety: hir::Unsafety,
|
pub unsafety: hir::Unsafety,
|
||||||
pub generics: Generics,
|
pub generic_params: Vec<GenericParam>,
|
||||||
pub decl: FnDecl,
|
pub decl: FnDecl,
|
||||||
pub abi: Abi,
|
pub abi: Abi,
|
||||||
}
|
}
|
||||||
|
@ -2722,11 +2737,7 @@ impl Clean<BareFunctionDecl> for hir::BareFnTy {
|
||||||
fn clean(&self, cx: &DocContext) -> BareFunctionDecl {
|
fn clean(&self, cx: &DocContext) -> BareFunctionDecl {
|
||||||
BareFunctionDecl {
|
BareFunctionDecl {
|
||||||
unsafety: self.unsafety,
|
unsafety: self.unsafety,
|
||||||
generics: Generics {
|
generic_params: self.generic_params.clean(cx),
|
||||||
lifetimes: self.lifetimes.clean(cx),
|
|
||||||
type_params: Vec::new(),
|
|
||||||
where_predicates: Vec::new()
|
|
||||||
},
|
|
||||||
decl: (&*self.decl, &self.arg_names[..]).clean(cx),
|
decl: (&*self.decl, &self.arg_names[..]).clean(cx),
|
||||||
abi: self.abi,
|
abi: self.abi,
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,30 +118,11 @@ impl<'a> fmt::Display for TyParamBounds<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for clean::Generics {
|
impl fmt::Display for clean::GenericParam {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if self.lifetimes.is_empty() && self.type_params.is_empty() { return Ok(()) }
|
match *self {
|
||||||
if f.alternate() {
|
clean::GenericParam::Lifetime(ref lp) => write!(f, "{}", lp),
|
||||||
f.write_str("<")?;
|
clean::GenericParam::Type(ref tp) => {
|
||||||
} else {
|
|
||||||
f.write_str("<")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i, life) in self.lifetimes.iter().enumerate() {
|
|
||||||
if i > 0 {
|
|
||||||
f.write_str(", ")?;
|
|
||||||
}
|
|
||||||
write!(f, "{}", *life)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.type_params.is_empty() {
|
|
||||||
if !self.lifetimes.is_empty() {
|
|
||||||
f.write_str(", ")?;
|
|
||||||
}
|
|
||||||
for (i, tp) in self.type_params.iter().enumerate() {
|
|
||||||
if i > 0 {
|
|
||||||
f.write_str(", ")?
|
|
||||||
}
|
|
||||||
f.write_str(&tp.name)?;
|
f.write_str(&tp.name)?;
|
||||||
|
|
||||||
if !tp.bounds.is_empty() {
|
if !tp.bounds.is_empty() {
|
||||||
|
@ -158,16 +139,23 @@ impl fmt::Display for clean::Generics {
|
||||||
} else {
|
} else {
|
||||||
write!(f, " = {}", ty)?;
|
write!(f, " = {}", ty)?;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if f.alternate() {
|
|
||||||
f.write_str(">")?;
|
|
||||||
} else {
|
|
||||||
f.write_str(">")?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for clean::Generics {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
if self.params.is_empty() { return Ok(()) }
|
||||||
|
if f.alternate() {
|
||||||
|
write!(f, "<{:#}>", CommaSep(&self.params))
|
||||||
|
} else {
|
||||||
|
write!(f, "<{}>", CommaSep(&self.params))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> fmt::Display for WhereClause<'a> {
|
impl<'a> fmt::Display for WhereClause<'a> {
|
||||||
|
@ -259,22 +247,11 @@ impl fmt::Display for clean::Lifetime {
|
||||||
|
|
||||||
impl fmt::Display for clean::PolyTrait {
|
impl fmt::Display for clean::PolyTrait {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if !self.lifetimes.is_empty() {
|
if !self.generic_params.is_empty() {
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
f.write_str("for<")?;
|
write!(f, "for<{:#}> ", CommaSep(&self.generic_params))?;
|
||||||
} else {
|
} else {
|
||||||
f.write_str("for<")?;
|
write!(f, "for<{}> ", CommaSep(&self.generic_params))?;
|
||||||
}
|
|
||||||
for (i, lt) in self.lifetimes.iter().enumerate() {
|
|
||||||
if i > 0 {
|
|
||||||
f.write_str(", ")?;
|
|
||||||
}
|
|
||||||
write!(f, "{}", lt)?;
|
|
||||||
}
|
|
||||||
if f.alternate() {
|
|
||||||
f.write_str("> ")?;
|
|
||||||
} else {
|
|
||||||
f.write_str("> ")?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
|
@ -602,12 +579,12 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
|
||||||
write!(f, "{}{:#}fn{:#}{:#}",
|
write!(f, "{}{:#}fn{:#}{:#}",
|
||||||
UnsafetySpace(decl.unsafety),
|
UnsafetySpace(decl.unsafety),
|
||||||
AbiSpace(decl.abi),
|
AbiSpace(decl.abi),
|
||||||
decl.generics,
|
CommaSep(&decl.generic_params),
|
||||||
decl.decl)
|
decl.decl)
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{}{}", UnsafetySpace(decl.unsafety), AbiSpace(decl.abi))?;
|
write!(f, "{}{}", UnsafetySpace(decl.unsafety), AbiSpace(decl.abi))?;
|
||||||
primitive_link(f, PrimitiveType::Fn, "fn")?;
|
primitive_link(f, PrimitiveType::Fn, "fn")?;
|
||||||
write!(f, "{}{}", decl.generics, decl.decl)
|
write!(f, "{}{}", CommaSep(&decl.generic_params), decl.decl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clean::Tuple(ref typs) => {
|
clean::Tuple(ref typs) => {
|
||||||
|
|
|
@ -1424,10 +1424,12 @@ impl DocFolder for Cache {
|
||||||
|
|
||||||
impl<'a> Cache {
|
impl<'a> Cache {
|
||||||
fn generics(&mut self, generics: &clean::Generics) {
|
fn generics(&mut self, generics: &clean::Generics) {
|
||||||
for typ in &generics.type_params {
|
for param in &generics.params {
|
||||||
|
if let clean::GenericParam::Type(ref typ) = *param {
|
||||||
self.typarams.insert(typ.did, typ.name.clone());
|
self.typarams.insert(typ.did, typ.name.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
|
|
|
@ -302,32 +302,58 @@ pub struct TyParam {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents lifetimes and type parameters attached to a declaration
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
/// of a function, enum, trait, etc.
|
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)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
pub struct Generics {
|
pub struct Generics {
|
||||||
pub lifetimes: Vec<LifetimeDef>,
|
pub params: Vec<GenericParam>,
|
||||||
pub ty_params: Vec<TyParam>,
|
|
||||||
pub where_clause: WhereClause,
|
pub where_clause: WhereClause,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Generics {
|
impl Generics {
|
||||||
pub fn is_lt_parameterized(&self) -> bool {
|
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 {
|
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 {
|
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> {
|
pub fn span_for_name(&self, name: &str) -> Option<Span> {
|
||||||
for t in &self.ty_params {
|
for param in &self.params {
|
||||||
|
if let GenericParam::Type(ref t) = *param {
|
||||||
if t.ident.name == name {
|
if t.ident.name == name {
|
||||||
return Some(t.span);
|
return Some(t.span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,8 +362,7 @@ impl Default for Generics {
|
||||||
/// Creates an instance of `Generics`.
|
/// Creates an instance of `Generics`.
|
||||||
fn default() -> Generics {
|
fn default() -> Generics {
|
||||||
Generics {
|
Generics {
|
||||||
lifetimes: Vec::new(),
|
params: Vec::new(),
|
||||||
ty_params: Vec::new(),
|
|
||||||
where_clause: WhereClause {
|
where_clause: WhereClause {
|
||||||
id: DUMMY_NODE_ID,
|
id: DUMMY_NODE_ID,
|
||||||
predicates: Vec::new(),
|
predicates: Vec::new(),
|
||||||
|
@ -373,8 +398,8 @@ pub enum WherePredicate {
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
pub struct WhereBoundPredicate {
|
pub struct WhereBoundPredicate {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
/// Any lifetimes from a `for` binding
|
/// Any generics from a `for` binding
|
||||||
pub bound_lifetimes: Vec<LifetimeDef>,
|
pub bound_generic_params: Vec<GenericParam>,
|
||||||
/// The type being bounded
|
/// The type being bounded
|
||||||
pub bounded_ty: P<Ty>,
|
pub bounded_ty: P<Ty>,
|
||||||
/// Trait and lifetime bounds (`Clone+Send+'static`)
|
/// Trait and lifetime bounds (`Clone+Send+'static`)
|
||||||
|
@ -1492,7 +1517,7 @@ impl fmt::Debug for Ty {
|
||||||
pub struct BareFnTy {
|
pub struct BareFnTy {
|
||||||
pub unsafety: Unsafety,
|
pub unsafety: Unsafety,
|
||||||
pub abi: Abi,
|
pub abi: Abi,
|
||||||
pub lifetimes: Vec<LifetimeDef>,
|
pub generic_params: Vec<GenericParam>,
|
||||||
pub decl: P<FnDecl>
|
pub decl: P<FnDecl>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1851,7 +1876,7 @@ pub struct TraitRef {
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
pub struct PolyTraitRef {
|
pub struct PolyTraitRef {
|
||||||
/// The `'a` in `<'a> Foo<&'a T>`
|
/// 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>`
|
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
|
||||||
pub trait_ref: TraitRef,
|
pub trait_ref: TraitRef,
|
||||||
|
@ -1860,9 +1885,9 @@ pub struct PolyTraitRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
PolyTraitRef {
|
||||||
bound_lifetimes: lifetimes,
|
bound_generic_params: generic_params,
|
||||||
trait_ref: TraitRef { path: path, ref_id: DUMMY_NODE_ID },
|
trait_ref: TraitRef { path: path, ref_id: DUMMY_NODE_ID },
|
||||||
span,
|
span,
|
||||||
}
|
}
|
||||||
|
|
|
@ -462,7 +462,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
|
|
||||||
fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef {
|
fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef {
|
||||||
ast::PolyTraitRef {
|
ast::PolyTraitRef {
|
||||||
bound_lifetimes: Vec::new(),
|
bound_generic_params: Vec::new(),
|
||||||
trait_ref: self.trait_ref(path),
|
trait_ref: self.trait_ref(path),
|
||||||
span,
|
span,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1748,22 +1748,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||||
visit::walk_vis(self, vis);
|
visit::walk_vis(self, vis);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_generics(&mut self, g: &'a ast::Generics) {
|
fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
|
||||||
for t in &g.ty_params {
|
let (attrs, explain) = match *param {
|
||||||
if !t.attrs.is_empty() {
|
ast::GenericParam::Lifetime(ref ld) =>
|
||||||
gate_feature_post!(&self, generic_param_attrs, t.attrs[0].span,
|
(&ld.attrs, "attributes on lifetime bindings are experimental"),
|
||||||
"attributes on type parameter bindings are experimental");
|
ast::GenericParam::Type(ref t) =>
|
||||||
}
|
(&t.attrs, "attributes on type parameter bindings are experimental"),
|
||||||
}
|
};
|
||||||
visit::walk_generics(self, g)
|
|
||||||
|
if !attrs.is_empty() {
|
||||||
|
gate_feature_post!(&self, generic_param_attrs, attrs[0].span, explain);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_lifetime_def(&mut self, lifetime_def: &'a ast::LifetimeDef) {
|
visit::walk_generic_param(self, param)
|
||||||
if !lifetime_def.attrs.is_empty() {
|
|
||||||
gate_feature_post!(&self, generic_param_attrs, lifetime_def.attrs[0].span,
|
|
||||||
"attributes on lifetime bindings are experimental");
|
|
||||||
}
|
|
||||||
visit::walk_lifetime_def(self, lifetime_def)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) {
|
fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) {
|
||||||
|
|
|
@ -237,8 +237,12 @@ pub trait Folder : Sized {
|
||||||
noop_fold_ty_param(tp, self)
|
noop_fold_ty_param(tp, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty_params(&mut self, tps: Vec<TyParam>) -> Vec<TyParam> {
|
fn fold_generic_param(&mut self, param: GenericParam) -> GenericParam {
|
||||||
noop_fold_ty_params(tps, self)
|
noop_fold_generic_param(param, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_generic_params(&mut self, params: Vec<GenericParam>) -> Vec<GenericParam> {
|
||||||
|
noop_fold_generic_params(params, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_tt(&mut self, tt: TokenTree) -> TokenTree {
|
fn fold_tt(&mut self, tt: TokenTree) -> TokenTree {
|
||||||
|
@ -363,8 +367,8 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
|
||||||
TyKind::Rptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt))
|
TyKind::Rptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt))
|
||||||
}
|
}
|
||||||
TyKind::BareFn(f) => {
|
TyKind::BareFn(f) => {
|
||||||
TyKind::BareFn(f.map(|BareFnTy {lifetimes, unsafety, abi, decl}| BareFnTy {
|
TyKind::BareFn(f.map(|BareFnTy {generic_params, unsafety, abi, decl}| BareFnTy {
|
||||||
lifetimes: fld.fold_lifetime_defs(lifetimes),
|
generic_params: fld.fold_generic_params(generic_params),
|
||||||
unsafety,
|
unsafety,
|
||||||
abi,
|
abi,
|
||||||
decl: fld.fold_fn_decl(decl)
|
decl: fld.fold_fn_decl(decl)
|
||||||
|
@ -677,8 +681,18 @@ pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noop_fold_ty_params<T: Folder>(tps: Vec<TyParam>, fld: &mut T) -> Vec<TyParam> {
|
pub fn noop_fold_generic_param<T: Folder>(param: GenericParam, fld: &mut T) -> GenericParam {
|
||||||
tps.move_map(|tp| fld.fold_ty_param(tp))
|
match param {
|
||||||
|
GenericParam::Lifetime(l) => GenericParam::Lifetime(fld.fold_lifetime_def(l)),
|
||||||
|
GenericParam::Type(t) => GenericParam::Type(fld.fold_ty_param(t)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn noop_fold_generic_params<T: Folder>(
|
||||||
|
params: Vec<GenericParam>,
|
||||||
|
fld: &mut T
|
||||||
|
) -> Vec<GenericParam> {
|
||||||
|
params.move_map(|p| fld.fold_generic_param(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noop_fold_lifetime<T: Folder>(l: Lifetime, fld: &mut T) -> Lifetime {
|
pub fn noop_fold_lifetime<T: Folder>(l: Lifetime, fld: &mut T) -> Lifetime {
|
||||||
|
@ -716,11 +730,10 @@ pub fn noop_fold_opt_lifetime<T: Folder>(o_lt: Option<Lifetime>, fld: &mut T)
|
||||||
o_lt.map(|lt| fld.fold_lifetime(lt))
|
o_lt.map(|lt| fld.fold_lifetime(lt))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noop_fold_generics<T: Folder>(Generics {ty_params, lifetimes, where_clause, span}: Generics,
|
pub fn noop_fold_generics<T: Folder>(Generics { params, where_clause, span }: Generics,
|
||||||
fld: &mut T) -> Generics {
|
fld: &mut T) -> Generics {
|
||||||
Generics {
|
Generics {
|
||||||
ty_params: fld.fold_ty_params(ty_params),
|
params: fld.fold_generic_params(params),
|
||||||
lifetimes: fld.fold_lifetime_defs(lifetimes),
|
|
||||||
where_clause: fld.fold_where_clause(where_clause),
|
where_clause: fld.fold_where_clause(where_clause),
|
||||||
span: fld.new_span(span),
|
span: fld.new_span(span),
|
||||||
}
|
}
|
||||||
|
@ -744,12 +757,12 @@ pub fn noop_fold_where_predicate<T: Folder>(
|
||||||
fld: &mut T)
|
fld: &mut T)
|
||||||
-> WherePredicate {
|
-> WherePredicate {
|
||||||
match pred {
|
match pred {
|
||||||
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{bound_lifetimes,
|
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{bound_generic_params,
|
||||||
bounded_ty,
|
bounded_ty,
|
||||||
bounds,
|
bounds,
|
||||||
span}) => {
|
span}) => {
|
||||||
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
||||||
bound_lifetimes: fld.fold_lifetime_defs(bound_lifetimes),
|
bound_generic_params: fld.fold_generic_params(bound_generic_params),
|
||||||
bounded_ty: fld.fold_ty(bounded_ty),
|
bounded_ty: fld.fold_ty(bounded_ty),
|
||||||
bounds: bounds.move_map(|x| fld.fold_ty_param_bound(x)),
|
bounds: bounds.move_map(|x| fld.fold_ty_param_bound(x)),
|
||||||
span: fld.new_span(span)
|
span: fld.new_span(span)
|
||||||
|
@ -806,7 +819,7 @@ pub fn noop_fold_trait_ref<T: Folder>(p: TraitRef, fld: &mut T) -> TraitRef {
|
||||||
|
|
||||||
pub fn noop_fold_poly_trait_ref<T: Folder>(p: PolyTraitRef, fld: &mut T) -> PolyTraitRef {
|
pub fn noop_fold_poly_trait_ref<T: Folder>(p: PolyTraitRef, fld: &mut T) -> PolyTraitRef {
|
||||||
ast::PolyTraitRef {
|
ast::PolyTraitRef {
|
||||||
bound_lifetimes: fld.fold_lifetime_defs(p.bound_lifetimes),
|
bound_generic_params: fld.fold_generic_params(p.bound_generic_params),
|
||||||
trait_ref: fld.fold_trait_ref(p.trait_ref),
|
trait_ref: fld.fold_trait_ref(p.trait_ref),
|
||||||
span: fld.new_span(p.span),
|
span: fld.new_span(p.span),
|
||||||
}
|
}
|
||||||
|
|
|
@ -905,9 +905,8 @@ mod tests {
|
||||||
node: ast::Constness::NotConst,
|
node: ast::Constness::NotConst,
|
||||||
},
|
},
|
||||||
Abi::Rust,
|
Abi::Rust,
|
||||||
ast::Generics{ // no idea on either of these:
|
ast::Generics{
|
||||||
lifetimes: Vec::new(),
|
params: Vec::new(),
|
||||||
ty_params: Vec::new(),
|
|
||||||
where_clause: ast::WhereClause {
|
where_clause: ast::WhereClause {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
predicates: Vec::new(),
|
predicates: Vec::new(),
|
||||||
|
|
|
@ -21,6 +21,7 @@ use ast::EnumDef;
|
||||||
use ast::{Expr, ExprKind, RangeLimits};
|
use ast::{Expr, ExprKind, RangeLimits};
|
||||||
use ast::{Field, FnDecl};
|
use ast::{Field, FnDecl};
|
||||||
use ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
|
use ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
|
||||||
|
use ast::GenericParam;
|
||||||
use ast::{Ident, ImplItem, IsAuto, Item, ItemKind};
|
use ast::{Ident, ImplItem, IsAuto, Item, ItemKind};
|
||||||
use ast::{Lifetime, LifetimeDef, Lit, LitKind, UintTy};
|
use ast::{Lifetime, LifetimeDef, Lit, LitKind, UintTy};
|
||||||
use ast::Local;
|
use ast::Local;
|
||||||
|
@ -1261,7 +1262,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// parse a TyKind::BareFn type:
|
/// parse a TyKind::BareFn type:
|
||||||
pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec<LifetimeDef>)
|
pub fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>)
|
||||||
-> PResult<'a, TyKind> {
|
-> PResult<'a, TyKind> {
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -1293,7 +1294,7 @@ impl<'a> Parser<'a> {
|
||||||
Ok(TyKind::BareFn(P(BareFnTy {
|
Ok(TyKind::BareFn(P(BareFnTy {
|
||||||
abi,
|
abi,
|
||||||
unsafety,
|
unsafety,
|
||||||
lifetimes: lifetime_defs,
|
generic_params,
|
||||||
decl,
|
decl,
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
@ -1582,9 +1583,9 @@ impl<'a> Parser<'a> {
|
||||||
Ok(P(ty))
|
Ok(P(ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_remaining_bounds(&mut self, lifetime_defs: Vec<LifetimeDef>, path: ast::Path,
|
fn parse_remaining_bounds(&mut self, generic_params: Vec<GenericParam>, path: ast::Path,
|
||||||
lo: Span, parse_plus: bool) -> PResult<'a, TyKind> {
|
lo: Span, parse_plus: bool) -> PResult<'a, TyKind> {
|
||||||
let poly_trait_ref = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span));
|
let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span));
|
||||||
let mut bounds = vec![TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)];
|
let mut bounds = vec![TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)];
|
||||||
if parse_plus {
|
if parse_plus {
|
||||||
self.bump(); // `+`
|
self.bump(); // `+`
|
||||||
|
@ -4550,9 +4551,8 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Parses (possibly empty) list of lifetime and type parameters, possibly including
|
/// Parses (possibly empty) list of lifetime and type parameters, possibly including
|
||||||
/// trailing comma and erroneous trailing attributes.
|
/// trailing comma and erroneous trailing attributes.
|
||||||
pub fn parse_generic_params(&mut self) -> PResult<'a, (Vec<LifetimeDef>, Vec<TyParam>)> {
|
pub fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> {
|
||||||
let mut lifetime_defs = Vec::new();
|
let mut params = Vec::new();
|
||||||
let mut ty_params = Vec::new();
|
|
||||||
let mut seen_ty_param = false;
|
let mut seen_ty_param = false;
|
||||||
loop {
|
loop {
|
||||||
let attrs = self.parse_outer_attributes()?;
|
let attrs = self.parse_outer_attributes()?;
|
||||||
|
@ -4564,18 +4564,18 @@ impl<'a> Parser<'a> {
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
lifetime_defs.push(LifetimeDef {
|
params.push(ast::GenericParam::Lifetime(LifetimeDef {
|
||||||
attrs: attrs.into(),
|
attrs: attrs.into(),
|
||||||
lifetime,
|
lifetime,
|
||||||
bounds,
|
bounds,
|
||||||
});
|
}));
|
||||||
if seen_ty_param {
|
if seen_ty_param {
|
||||||
self.span_err(self.prev_span,
|
self.span_err(self.prev_span,
|
||||||
"lifetime parameters must be declared prior to type parameters");
|
"lifetime parameters must be declared prior to type parameters");
|
||||||
}
|
}
|
||||||
} else if self.check_ident() {
|
} else if self.check_ident() {
|
||||||
// Parse type parameter.
|
// Parse type parameter.
|
||||||
ty_params.push(self.parse_ty_param(attrs)?);
|
params.push(ast::GenericParam::Type(self.parse_ty_param(attrs)?));
|
||||||
seen_ty_param = true;
|
seen_ty_param = true;
|
||||||
} else {
|
} else {
|
||||||
// Check for trailing attributes and stop parsing.
|
// Check for trailing attributes and stop parsing.
|
||||||
|
@ -4591,7 +4591,7 @@ impl<'a> Parser<'a> {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok((lifetime_defs, ty_params))
|
Ok(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a set of optional generic type parameter declarations. Where
|
/// Parse a set of optional generic type parameter declarations. Where
|
||||||
|
@ -4606,11 +4606,10 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
let span_lo = self.span;
|
let span_lo = self.span;
|
||||||
if self.eat_lt() {
|
if self.eat_lt() {
|
||||||
let (lifetime_defs, ty_params) = self.parse_generic_params()?;
|
let params = self.parse_generic_params()?;
|
||||||
self.expect_gt()?;
|
self.expect_gt()?;
|
||||||
Ok(ast::Generics {
|
Ok(ast::Generics {
|
||||||
lifetimes: lifetime_defs,
|
params,
|
||||||
ty_params,
|
|
||||||
where_clause: WhereClause {
|
where_clause: WhereClause {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
predicates: Vec::new(),
|
predicates: Vec::new(),
|
||||||
|
@ -4738,7 +4737,7 @@ impl<'a> Parser<'a> {
|
||||||
where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
|
where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
|
||||||
ast::WhereBoundPredicate {
|
ast::WhereBoundPredicate {
|
||||||
span: lo.to(self.prev_span),
|
span: lo.to(self.prev_span),
|
||||||
bound_lifetimes: lifetime_defs,
|
bound_generic_params: lifetime_defs,
|
||||||
bounded_ty: ty,
|
bounded_ty: ty,
|
||||||
bounds,
|
bounds,
|
||||||
}
|
}
|
||||||
|
@ -5363,16 +5362,24 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<LifetimeDef>> {
|
fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
|
||||||
if self.eat_keyword(keywords::For) {
|
if self.eat_keyword(keywords::For) {
|
||||||
self.expect_lt()?;
|
self.expect_lt()?;
|
||||||
let (lifetime_defs, ty_params) = self.parse_generic_params()?;
|
let params = self.parse_generic_params()?;
|
||||||
self.expect_gt()?;
|
self.expect_gt()?;
|
||||||
if !ty_params.is_empty() {
|
|
||||||
self.span_err(ty_params[0].span,
|
let first_non_lifetime_param_span = params.iter()
|
||||||
"only lifetime parameters can be used in this context");
|
.filter_map(|param| match *param {
|
||||||
|
ast::GenericParam::Lifetime(_) => None,
|
||||||
|
ast::GenericParam::Type(ref t) => Some(t.span),
|
||||||
|
})
|
||||||
|
.next();
|
||||||
|
|
||||||
|
if let Some(span) = first_non_lifetime_param_span {
|
||||||
|
self.span_err(span, "only lifetime parameters can be used in this context");
|
||||||
}
|
}
|
||||||
Ok(lifetime_defs)
|
|
||||||
|
Ok(params)
|
||||||
} else {
|
} else {
|
||||||
Ok(Vec::new())
|
Ok(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,7 +275,7 @@ pub fn token_to_string(tok: &Token) -> String {
|
||||||
token::NtArm(ref e) => arm_to_string(e),
|
token::NtArm(ref e) => arm_to_string(e),
|
||||||
token::NtImplItem(ref e) => impl_item_to_string(e),
|
token::NtImplItem(ref e) => impl_item_to_string(e),
|
||||||
token::NtTraitItem(ref e) => trait_item_to_string(e),
|
token::NtTraitItem(ref e) => trait_item_to_string(e),
|
||||||
token::NtGenerics(ref e) => generics_to_string(e),
|
token::NtGenerics(ref e) => generic_params_to_string(&e.params),
|
||||||
token::NtWhereClause(ref e) => where_clause_to_string(e),
|
token::NtWhereClause(ref e) => where_clause_to_string(e),
|
||||||
token::NtArg(ref e) => arg_to_string(e),
|
token::NtArg(ref e) => arg_to_string(e),
|
||||||
token::NtVis(ref e) => vis_to_string(e),
|
token::NtVis(ref e) => vis_to_string(e),
|
||||||
|
@ -339,8 +339,8 @@ pub fn trait_item_to_string(i: &ast::TraitItem) -> String {
|
||||||
to_string(|s| s.print_trait_item(i))
|
to_string(|s| s.print_trait_item(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generics_to_string(generics: &ast::Generics) -> String {
|
pub fn generic_params_to_string(generic_params: &[ast::GenericParam]) -> String {
|
||||||
to_string(|s| s.print_generics(generics))
|
to_string(|s| s.print_generic_params(generic_params))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn where_clause_to_string(i: &ast::WhereClause) -> String {
|
pub fn where_clause_to_string(i: &ast::WhereClause) -> String {
|
||||||
|
@ -1043,21 +1043,11 @@ impl<'a> State<'a> {
|
||||||
self.pclose()?;
|
self.pclose()?;
|
||||||
}
|
}
|
||||||
ast::TyKind::BareFn(ref f) => {
|
ast::TyKind::BareFn(ref f) => {
|
||||||
let generics = ast::Generics {
|
|
||||||
lifetimes: f.lifetimes.clone(),
|
|
||||||
ty_params: Vec::new(),
|
|
||||||
where_clause: ast::WhereClause {
|
|
||||||
id: ast::DUMMY_NODE_ID,
|
|
||||||
predicates: Vec::new(),
|
|
||||||
span: syntax_pos::DUMMY_SP,
|
|
||||||
},
|
|
||||||
span: syntax_pos::DUMMY_SP,
|
|
||||||
};
|
|
||||||
self.print_ty_fn(f.abi,
|
self.print_ty_fn(f.abi,
|
||||||
f.unsafety,
|
f.unsafety,
|
||||||
&f.decl,
|
&f.decl,
|
||||||
None,
|
None,
|
||||||
&generics)?;
|
&f.generic_params)?;
|
||||||
}
|
}
|
||||||
ast::TyKind::Path(None, ref path) => {
|
ast::TyKind::Path(None, ref path) => {
|
||||||
self.print_path(path, false, 0, false)?;
|
self.print_path(path, false, 0, false)?;
|
||||||
|
@ -1271,15 +1261,15 @@ impl<'a> State<'a> {
|
||||||
self.s.word(&ga.asm.as_str())?;
|
self.s.word(&ga.asm.as_str())?;
|
||||||
self.end()?;
|
self.end()?;
|
||||||
}
|
}
|
||||||
ast::ItemKind::Ty(ref ty, ref params) => {
|
ast::ItemKind::Ty(ref ty, ref generics) => {
|
||||||
self.ibox(INDENT_UNIT)?;
|
self.ibox(INDENT_UNIT)?;
|
||||||
self.ibox(0)?;
|
self.ibox(0)?;
|
||||||
self.word_nbsp(&visibility_qualified(&item.vis, "type"))?;
|
self.word_nbsp(&visibility_qualified(&item.vis, "type"))?;
|
||||||
self.print_ident(item.ident)?;
|
self.print_ident(item.ident)?;
|
||||||
self.print_generics(params)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
self.end()?; // end the inner ibox
|
self.end()?; // end the inner ibox
|
||||||
|
|
||||||
self.print_where_clause(¶ms.where_clause)?;
|
self.print_where_clause(&generics.where_clause)?;
|
||||||
self.s.space()?;
|
self.s.space()?;
|
||||||
self.word_space("=")?;
|
self.word_space("=")?;
|
||||||
self.print_type(ty)?;
|
self.print_type(ty)?;
|
||||||
|
@ -1329,7 +1319,7 @@ impl<'a> State<'a> {
|
||||||
self.word_nbsp("impl")?;
|
self.word_nbsp("impl")?;
|
||||||
|
|
||||||
if generics.is_parameterized() {
|
if generics.is_parameterized() {
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
self.s.space()?;
|
self.s.space()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1361,7 +1351,7 @@ impl<'a> State<'a> {
|
||||||
self.print_is_auto(is_auto)?;
|
self.print_is_auto(is_auto)?;
|
||||||
self.word_nbsp("trait")?;
|
self.word_nbsp("trait")?;
|
||||||
self.print_ident(item.ident)?;
|
self.print_ident(item.ident)?;
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
let mut real_bounds = Vec::with_capacity(bounds.len());
|
let mut real_bounds = Vec::with_capacity(bounds.len());
|
||||||
for b in bounds.iter() {
|
for b in bounds.iter() {
|
||||||
if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
|
if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
|
||||||
|
@ -1386,7 +1376,7 @@ impl<'a> State<'a> {
|
||||||
self.print_visibility(&item.vis)?;
|
self.print_visibility(&item.vis)?;
|
||||||
self.word_nbsp("trait")?;
|
self.word_nbsp("trait")?;
|
||||||
self.print_ident(item.ident)?;
|
self.print_ident(item.ident)?;
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
let mut real_bounds = Vec::with_capacity(bounds.len());
|
let mut real_bounds = Vec::with_capacity(bounds.len());
|
||||||
// FIXME(durka) this seems to be some quite outdated syntax
|
// FIXME(durka) this seems to be some quite outdated syntax
|
||||||
for b in bounds.iter() {
|
for b in bounds.iter() {
|
||||||
|
@ -1432,26 +1422,20 @@ impl<'a> State<'a> {
|
||||||
self.print_path(&t.path, false, 0, false)
|
self.print_path(&t.path, false, 0, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::Result<()> {
|
fn print_formal_generic_params(
|
||||||
if !lifetimes.is_empty() {
|
&mut self,
|
||||||
self.s.word("for<")?;
|
generic_params: &[ast::GenericParam]
|
||||||
let mut comma = false;
|
) -> io::Result<()> {
|
||||||
for lifetime_def in lifetimes {
|
if !generic_params.is_empty() {
|
||||||
if comma {
|
self.s.word("for")?;
|
||||||
self.word_space(",")?
|
self.print_generic_params(generic_params)?;
|
||||||
}
|
|
||||||
self.print_outer_attributes_inline(&lifetime_def.attrs)?;
|
|
||||||
self.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds)?;
|
|
||||||
comma = true;
|
|
||||||
}
|
|
||||||
self.s.word(">")?;
|
|
||||||
self.nbsp()?;
|
self.nbsp()?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> io::Result<()> {
|
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> io::Result<()> {
|
||||||
self.print_formal_lifetime_list(&t.bound_lifetimes)?;
|
self.print_formal_generic_params(&t.bound_generic_params)?;
|
||||||
self.print_trait_ref(&t.trait_ref)
|
self.print_trait_ref(&t.trait_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1461,7 +1445,7 @@ impl<'a> State<'a> {
|
||||||
visibility: &ast::Visibility) -> io::Result<()> {
|
visibility: &ast::Visibility) -> io::Result<()> {
|
||||||
self.head(&visibility_qualified(visibility, "enum"))?;
|
self.head(&visibility_qualified(visibility, "enum"))?;
|
||||||
self.print_ident(ident)?;
|
self.print_ident(ident)?;
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
self.print_where_clause(&generics.where_clause)?;
|
self.print_where_clause(&generics.where_clause)?;
|
||||||
self.s.space()?;
|
self.s.space()?;
|
||||||
self.print_variants(&enum_definition.variants, span)
|
self.print_variants(&enum_definition.variants, span)
|
||||||
|
@ -1517,7 +1501,7 @@ impl<'a> State<'a> {
|
||||||
span: syntax_pos::Span,
|
span: syntax_pos::Span,
|
||||||
print_finalizer: bool) -> io::Result<()> {
|
print_finalizer: bool) -> io::Result<()> {
|
||||||
self.print_ident(ident)?;
|
self.print_ident(ident)?;
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
if !struct_def.is_struct() {
|
if !struct_def.is_struct() {
|
||||||
if struct_def.is_tuple() {
|
if struct_def.is_tuple() {
|
||||||
self.popen()?;
|
self.popen()?;
|
||||||
|
@ -2764,7 +2748,7 @@ impl<'a> State<'a> {
|
||||||
self.nbsp()?;
|
self.nbsp()?;
|
||||||
self.print_ident(name)?;
|
self.print_ident(name)?;
|
||||||
}
|
}
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(&generics.params)?;
|
||||||
self.print_fn_args_and_ret(decl)?;
|
self.print_fn_args_and_ret(decl)?;
|
||||||
self.print_where_clause(&generics.where_clause)
|
self.print_where_clause(&generics.where_clause)
|
||||||
}
|
}
|
||||||
|
@ -2870,31 +2854,23 @@ impl<'a> State<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_generics(&mut self,
|
pub fn print_generic_params(
|
||||||
generics: &ast::Generics)
|
&mut self,
|
||||||
-> io::Result<()>
|
generic_params: &[ast::GenericParam]
|
||||||
{
|
) -> io::Result<()> {
|
||||||
let total = generics.lifetimes.len() + generics.ty_params.len();
|
if generic_params.is_empty() {
|
||||||
if total == 0 {
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.s.word("<")?;
|
self.s.word("<")?;
|
||||||
|
|
||||||
let mut ints = Vec::new();
|
self.commasep(Inconsistent, &generic_params, |s, param| {
|
||||||
for i in 0..total {
|
match *param {
|
||||||
ints.push(i);
|
ast::GenericParam::Lifetime(ref lifetime_def) => {
|
||||||
}
|
|
||||||
|
|
||||||
self.commasep(Inconsistent, &ints[..], |s, &idx| {
|
|
||||||
if idx < generics.lifetimes.len() {
|
|
||||||
let lifetime_def = &generics.lifetimes[idx];
|
|
||||||
s.print_outer_attributes_inline(&lifetime_def.attrs)?;
|
s.print_outer_attributes_inline(&lifetime_def.attrs)?;
|
||||||
s.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds)
|
s.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds)
|
||||||
} else {
|
},
|
||||||
let idx = idx - generics.lifetimes.len();
|
ast::GenericParam::Type(ref ty_param) => s.print_ty_param(ty_param),
|
||||||
let param = &generics.ty_params[idx];
|
|
||||||
s.print_ty_param(param)
|
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -2931,11 +2907,13 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match *predicate {
|
match *predicate {
|
||||||
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bound_lifetimes,
|
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
||||||
|
ref bound_generic_params,
|
||||||
ref bounded_ty,
|
ref bounded_ty,
|
||||||
ref bounds,
|
ref bounds,
|
||||||
..}) => {
|
..
|
||||||
self.print_formal_lifetime_list(bound_lifetimes)?;
|
}) => {
|
||||||
|
self.print_formal_generic_params(bound_generic_params)?;
|
||||||
self.print_type(bounded_ty)?;
|
self.print_type(bounded_ty)?;
|
||||||
self.print_bounds(":", bounds)?;
|
self.print_bounds(":", bounds)?;
|
||||||
}
|
}
|
||||||
|
@ -3057,16 +3035,15 @@ impl<'a> State<'a> {
|
||||||
unsafety: ast::Unsafety,
|
unsafety: ast::Unsafety,
|
||||||
decl: &ast::FnDecl,
|
decl: &ast::FnDecl,
|
||||||
name: Option<ast::Ident>,
|
name: Option<ast::Ident>,
|
||||||
generics: &ast::Generics)
|
generic_params: &Vec<ast::GenericParam>)
|
||||||
-> io::Result<()> {
|
-> io::Result<()> {
|
||||||
self.ibox(INDENT_UNIT)?;
|
self.ibox(INDENT_UNIT)?;
|
||||||
if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() {
|
if !generic_params.is_empty() {
|
||||||
self.s.word("for")?;
|
self.s.word("for")?;
|
||||||
self.print_generics(generics)?;
|
self.print_generic_params(generic_params)?;
|
||||||
}
|
}
|
||||||
let generics = ast::Generics {
|
let generics = ast::Generics {
|
||||||
lifetimes: Vec::new(),
|
params: Vec::new(),
|
||||||
ty_params: Vec::new(),
|
|
||||||
where_clause: ast::WhereClause {
|
where_clause: ast::WhereClause {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
predicates: Vec::new(),
|
predicates: Vec::new(),
|
||||||
|
|
|
@ -363,7 +363,10 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
|
||||||
ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true,
|
ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true,
|
||||||
_ => false
|
_ => false
|
||||||
};
|
};
|
||||||
let tparm_cnt = generics.ty_params.len();
|
let tparm_cnt = generics.params.iter()
|
||||||
|
.filter(|param| param.is_type_param())
|
||||||
|
.count();
|
||||||
|
|
||||||
// NB: inadequate check, but we're running
|
// NB: inadequate check, but we're running
|
||||||
// well before resolve, can't get too deep.
|
// well before resolve, can't get too deep.
|
||||||
input_cnt == 1
|
input_cnt == 1
|
||||||
|
|
|
@ -71,6 +71,10 @@ impl<'ast> Visitor<'ast> for NodeCounter {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
walk_ty(self, t)
|
walk_ty(self, t)
|
||||||
}
|
}
|
||||||
|
fn visit_generic_param(&mut self, param: &GenericParam) {
|
||||||
|
self.count += 1;
|
||||||
|
walk_generic_param(self, param)
|
||||||
|
}
|
||||||
fn visit_generics(&mut self, g: &Generics) {
|
fn visit_generics(&mut self, g: &Generics) {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
walk_generics(self, g)
|
walk_generics(self, g)
|
||||||
|
@ -121,10 +125,6 @@ impl<'ast> Visitor<'ast> for NodeCounter {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
walk_lifetime(self, lifetime)
|
walk_lifetime(self, lifetime)
|
||||||
}
|
}
|
||||||
fn visit_lifetime_def(&mut self, lifetime: &LifetimeDef) {
|
|
||||||
self.count += 1;
|
|
||||||
walk_lifetime_def(self, lifetime)
|
|
||||||
}
|
|
||||||
fn visit_mac(&mut self, _mac: &Mac) {
|
fn visit_mac(&mut self, _mac: &Mac) {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
walk_mac(self, _mac)
|
walk_mac(self, _mac)
|
||||||
|
|
|
@ -72,6 +72,7 @@ pub trait Visitor<'ast>: Sized {
|
||||||
fn visit_expr(&mut self, ex: &'ast Expr) { walk_expr(self, ex) }
|
fn visit_expr(&mut self, ex: &'ast Expr) { walk_expr(self, ex) }
|
||||||
fn visit_expr_post(&mut self, _ex: &'ast Expr) { }
|
fn visit_expr_post(&mut self, _ex: &'ast Expr) { }
|
||||||
fn visit_ty(&mut self, t: &'ast Ty) { walk_ty(self, t) }
|
fn visit_ty(&mut self, t: &'ast Ty) { walk_ty(self, t) }
|
||||||
|
fn visit_generic_param(&mut self, param: &'ast GenericParam) { walk_generic_param(self, param) }
|
||||||
fn visit_generics(&mut self, g: &'ast Generics) { walk_generics(self, g) }
|
fn visit_generics(&mut self, g: &'ast Generics) { walk_generics(self, g) }
|
||||||
fn visit_where_predicate(&mut self, p: &'ast WherePredicate) {
|
fn visit_where_predicate(&mut self, p: &'ast WherePredicate) {
|
||||||
walk_where_predicate(self, p)
|
walk_where_predicate(self, p)
|
||||||
|
@ -103,9 +104,6 @@ pub trait Visitor<'ast>: Sized {
|
||||||
fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) {
|
fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) {
|
||||||
walk_lifetime(self, lifetime)
|
walk_lifetime(self, lifetime)
|
||||||
}
|
}
|
||||||
fn visit_lifetime_def(&mut self, lifetime: &'ast LifetimeDef) {
|
|
||||||
walk_lifetime_def(self, lifetime)
|
|
||||||
}
|
|
||||||
fn visit_mac(&mut self, _mac: &'ast Mac) {
|
fn visit_mac(&mut self, _mac: &'ast Mac) {
|
||||||
panic!("visit_mac disabled by default");
|
panic!("visit_mac disabled by default");
|
||||||
// NB: see note about macros above.
|
// NB: see note about macros above.
|
||||||
|
@ -210,18 +208,12 @@ pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime
|
||||||
visitor.visit_ident(lifetime.span, lifetime.ident);
|
visitor.visit_ident(lifetime.span, lifetime.ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_lifetime_def<'a, V: Visitor<'a>>(visitor: &mut V, lifetime_def: &'a LifetimeDef) {
|
|
||||||
visitor.visit_lifetime(&lifetime_def.lifetime);
|
|
||||||
walk_list!(visitor, visit_lifetime, &lifetime_def.bounds);
|
|
||||||
walk_list!(visitor, visit_attribute, &*lifetime_def.attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V,
|
pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V,
|
||||||
trait_ref: &'a PolyTraitRef,
|
trait_ref: &'a PolyTraitRef,
|
||||||
_: &TraitBoundModifier)
|
_: &TraitBoundModifier)
|
||||||
where V: Visitor<'a>,
|
where V: Visitor<'a>,
|
||||||
{
|
{
|
||||||
walk_list!(visitor, visit_lifetime_def, &trait_ref.bound_lifetimes);
|
walk_list!(visitor, visit_generic_param, &trait_ref.bound_generic_params);
|
||||||
visitor.visit_trait_ref(&trait_ref.trait_ref);
|
visitor.visit_trait_ref(&trait_ref.trait_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +331,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
|
||||||
}
|
}
|
||||||
TyKind::BareFn(ref function_declaration) => {
|
TyKind::BareFn(ref function_declaration) => {
|
||||||
walk_fn_decl(visitor, &function_declaration.decl);
|
walk_fn_decl(visitor, &function_declaration.decl);
|
||||||
walk_list!(visitor, visit_lifetime_def, &function_declaration.lifetimes);
|
walk_list!(visitor, visit_generic_param, &function_declaration.generic_params);
|
||||||
}
|
}
|
||||||
TyKind::Path(ref maybe_qself, ref path) => {
|
TyKind::Path(ref maybe_qself, ref path) => {
|
||||||
if let Some(ref qself) = *maybe_qself {
|
if let Some(ref qself) = *maybe_qself {
|
||||||
|
@ -499,14 +491,24 @@ pub fn walk_ty_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a TyPar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) {
|
pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a GenericParam) {
|
||||||
for param in &generics.ty_params {
|
match *param {
|
||||||
visitor.visit_ident(param.span, param.ident);
|
GenericParam::Lifetime(ref l) => {
|
||||||
walk_list!(visitor, visit_ty_param_bound, ¶m.bounds);
|
visitor.visit_lifetime(&l.lifetime);
|
||||||
walk_list!(visitor, visit_ty, ¶m.default);
|
walk_list!(visitor, visit_lifetime, &l.bounds);
|
||||||
walk_list!(visitor, visit_attribute, &*param.attrs);
|
walk_list!(visitor, visit_attribute, &*l.attrs);
|
||||||
}
|
}
|
||||||
walk_list!(visitor, visit_lifetime_def, &generics.lifetimes);
|
GenericParam::Type(ref t) => {
|
||||||
|
visitor.visit_ident(t.span, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) {
|
||||||
|
walk_list!(visitor, visit_generic_param, &generics.params);
|
||||||
walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates);
|
walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,11 +516,11 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a
|
||||||
match *predicate {
|
match *predicate {
|
||||||
WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty,
|
WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty,
|
||||||
ref bounds,
|
ref bounds,
|
||||||
ref bound_lifetimes,
|
ref bound_generic_params,
|
||||||
..}) => {
|
..}) => {
|
||||||
visitor.visit_ty(bounded_ty);
|
visitor.visit_ty(bounded_ty);
|
||||||
walk_list!(visitor, visit_ty_param_bound, bounds);
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||||
walk_list!(visitor, visit_lifetime_def, bound_lifetimes);
|
walk_list!(visitor, visit_generic_param, bound_generic_params);
|
||||||
}
|
}
|
||||||
WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime,
|
WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime,
|
||||||
ref bounds,
|
ref bounds,
|
||||||
|
|
|
@ -45,15 +45,23 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
|
||||||
match *item {
|
match *item {
|
||||||
Annotatable::Item(ref annitem) => {
|
Annotatable::Item(ref annitem) => {
|
||||||
match annitem.node {
|
match annitem.node {
|
||||||
ItemKind::Struct(_, Generics { ref ty_params, .. }) |
|
ItemKind::Struct(_, Generics { ref params, .. }) |
|
||||||
ItemKind::Enum(_, Generics { ref ty_params, .. })
|
ItemKind::Enum(_, Generics { ref params, .. }) => {
|
||||||
if attr::contains_name(&annitem.attrs, "rustc_copy_clone_marker") &&
|
if attr::contains_name(&annitem.attrs, "rustc_copy_clone_marker") &&
|
||||||
ty_params.is_empty() => {
|
!params.iter().any(|param| param.is_type_param())
|
||||||
|
{
|
||||||
bounds = vec![];
|
bounds = vec![];
|
||||||
is_shallow = true;
|
is_shallow = true;
|
||||||
substructure = combine_substructure(Box::new(|c, s, sub| {
|
substructure = combine_substructure(Box::new(|c, s, sub| {
|
||||||
cs_clone_shallow("Clone", c, s, sub, false)
|
cs_clone_shallow("Clone", c, s, sub, false)
|
||||||
}));
|
}));
|
||||||
|
} else {
|
||||||
|
bounds = vec![];
|
||||||
|
is_shallow = false;
|
||||||
|
substructure = combine_substructure(Box::new(|c, s, sub| {
|
||||||
|
cs_clone("Clone", c, s, sub)
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ItemKind::Union(..) => {
|
ItemKind::Union(..) => {
|
||||||
bounds = vec![Literal(path_std!(cx, marker::Copy))];
|
bounds = vec![Literal(path_std!(cx, marker::Copy))];
|
||||||
|
|
|
@ -192,7 +192,9 @@ use std::collections::HashSet;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
use syntax::abi::Abi;
|
use syntax::abi::Abi;
|
||||||
use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind, VariantData};
|
use syntax::ast::{
|
||||||
|
self, BinOpKind, EnumDef, Expr, GenericParam, Generics, Ident, PatKind, VariantData
|
||||||
|
};
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::ext::base::{Annotatable, ExtCtxt};
|
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
|
@ -417,7 +419,7 @@ impl<'a> TraitDef<'a> {
|
||||||
ast::ItemKind::Struct(_, ref generics) |
|
ast::ItemKind::Struct(_, ref generics) |
|
||||||
ast::ItemKind::Enum(_, ref generics) |
|
ast::ItemKind::Enum(_, ref generics) |
|
||||||
ast::ItemKind::Union(_, ref generics) => {
|
ast::ItemKind::Union(_, ref generics) => {
|
||||||
generics.ty_params.is_empty()
|
!generics.params.iter().any(|p| p.is_type_param())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Non-ADT derive is an error, but it should have been
|
// Non-ADT derive is an error, but it should have been
|
||||||
|
@ -537,18 +539,19 @@ impl<'a> TraitDef<'a> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let Generics { mut lifetimes, mut ty_params, mut where_clause, span } = self.generics
|
let Generics { mut params, mut where_clause, span } = self.generics
|
||||||
.to_generics(cx, self.span, type_ident, generics);
|
.to_generics(cx, self.span, type_ident, generics);
|
||||||
|
|
||||||
// Copy the lifetimes
|
// Create the generic parameters
|
||||||
lifetimes.extend(generics.lifetimes.iter().cloned());
|
params.extend(generics.params.iter().map(|param| {
|
||||||
|
match *param {
|
||||||
// Create the type parameters.
|
ref l @ GenericParam::Lifetime(_) => l.clone(),
|
||||||
ty_params.extend(generics.ty_params.iter().map(|ty_param| {
|
GenericParam::Type(ref ty_param) => {
|
||||||
// I don't think this can be moved out of the loop, since
|
// I don't think this can be moved out of the loop, since
|
||||||
// a TyParamBound requires an ast id
|
// a TyParamBound requires an ast id
|
||||||
let mut bounds: Vec<_> =
|
let mut bounds: Vec<_> =
|
||||||
// extra restrictions on the generics parameters to the type being derived upon
|
// extra restrictions on the generics parameters to the
|
||||||
|
// type being derived upon
|
||||||
self.additional_bounds.iter().map(|p| {
|
self.additional_bounds.iter().map(|p| {
|
||||||
cx.typarambound(p.to_path(cx, self.span,
|
cx.typarambound(p.to_path(cx, self.span,
|
||||||
type_ident, generics))
|
type_ident, generics))
|
||||||
|
@ -562,7 +565,9 @@ impl<'a> TraitDef<'a> {
|
||||||
bounds.push((*declared_bound).clone());
|
bounds.push((*declared_bound).clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.typaram(self.span, ty_param.ident, vec![], bounds, None)
|
GenericParam::Type(cx.typaram(self.span, ty_param.ident, vec![], bounds, None))
|
||||||
|
}
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// and similarly for where clauses
|
// and similarly for where clauses
|
||||||
|
@ -571,7 +576,7 @@ impl<'a> TraitDef<'a> {
|
||||||
ast::WherePredicate::BoundPredicate(ref wb) => {
|
ast::WherePredicate::BoundPredicate(ref wb) => {
|
||||||
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
||||||
span: self.span,
|
span: self.span,
|
||||||
bound_lifetimes: wb.bound_lifetimes.clone(),
|
bound_generic_params: wb.bound_generic_params.clone(),
|
||||||
bounded_ty: wb.bounded_ty.clone(),
|
bounded_ty: wb.bounded_ty.clone(),
|
||||||
bounds: wb.bounds.iter().cloned().collect(),
|
bounds: wb.bounds.iter().cloned().collect(),
|
||||||
})
|
})
|
||||||
|
@ -594,8 +599,18 @@ impl<'a> TraitDef<'a> {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if !ty_params.is_empty() {
|
{
|
||||||
let ty_param_names: Vec<ast::Name> = ty_params.iter()
|
// 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::GenericParam::Type(ref t) => Some(t),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.peekable();
|
||||||
|
|
||||||
|
if ty_params.peek().is_some() {
|
||||||
|
let ty_param_names: Vec<ast::Name> = ty_params
|
||||||
.map(|ty_param| ty_param.ident.name)
|
.map(|ty_param| ty_param.ident.name)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -615,7 +630,9 @@ impl<'a> TraitDef<'a> {
|
||||||
}
|
}
|
||||||
let mut bounds: Vec<_> = self.additional_bounds
|
let mut bounds: Vec<_> = self.additional_bounds
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| cx.typarambound(p.to_path(cx, self.span, type_ident, generics)))
|
.map(|p| {
|
||||||
|
cx.typarambound(p.to_path(cx, self.span, type_ident, generics))
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// require the current trait
|
// require the current trait
|
||||||
|
@ -623,7 +640,7 @@ impl<'a> TraitDef<'a> {
|
||||||
|
|
||||||
let predicate = ast::WhereBoundPredicate {
|
let predicate = ast::WhereBoundPredicate {
|
||||||
span: self.span,
|
span: self.span,
|
||||||
bound_lifetimes: vec![],
|
bound_generic_params: Vec::new(),
|
||||||
bounded_ty: ty,
|
bounded_ty: ty,
|
||||||
bounds,
|
bounds,
|
||||||
};
|
};
|
||||||
|
@ -633,10 +650,10 @@ impl<'a> TraitDef<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let trait_generics = Generics {
|
let trait_generics = Generics {
|
||||||
lifetimes,
|
params,
|
||||||
ty_params,
|
|
||||||
where_clause,
|
where_clause,
|
||||||
span,
|
span,
|
||||||
};
|
};
|
||||||
|
@ -645,14 +662,21 @@ impl<'a> TraitDef<'a> {
|
||||||
let trait_ref = cx.trait_ref(trait_path);
|
let trait_ref = cx.trait_ref(trait_path);
|
||||||
|
|
||||||
// Create the type parameters on the `self` path.
|
// Create the type parameters on the `self` path.
|
||||||
let self_ty_params = generics.ty_params
|
let self_ty_params = generics.params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty_param| cx.ty_ident(self.span, ty_param.ident))
|
.filter_map(|param| match *param {
|
||||||
|
GenericParam::Type(ref ty_param)
|
||||||
|
=> Some(cx.ty_ident(self.span, ty_param.ident)),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let self_lifetimes: Vec<ast::Lifetime> = generics.lifetimes
|
let self_lifetimes: Vec<ast::Lifetime> = generics.params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ld| ld.lifetime)
|
.filter_map(|param| match *param {
|
||||||
|
GenericParam::Lifetime(ref ld) => Some(ld.lifetime),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Create the type of `self`.
|
// Create the type of `self`.
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub use self::PtrTy::*;
|
||||||
pub use self::Ty::*;
|
pub use self::Ty::*;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast::{Expr, Generics, Ident, SelfKind};
|
use syntax::ast::{Expr, GenericParam, Generics, Ident, SelfKind};
|
||||||
use syntax::ext::base::ExtCtxt;
|
use syntax::ext::base::ExtCtxt;
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
use syntax::codemap::respan;
|
use syntax::codemap::respan;
|
||||||
|
@ -185,13 +185,20 @@ impl<'a> Ty<'a> {
|
||||||
-> ast::Path {
|
-> ast::Path {
|
||||||
match *self {
|
match *self {
|
||||||
Self_ => {
|
Self_ => {
|
||||||
let self_params = self_generics.ty_params
|
let self_params = self_generics.params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty_param| cx.ty_ident(span, ty_param.ident))
|
.filter_map(|param| match *param {
|
||||||
|
GenericParam::Type(ref ty_param) => Some(cx.ty_ident(span, ty_param.ident)),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let lifetimes = self_generics.lifetimes
|
|
||||||
|
let lifetimes: Vec<ast::Lifetime> = self_generics.params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|d| d.lifetime)
|
.filter_map(|param| match *param {
|
||||||
|
GenericParam::Lifetime(ref ld) => Some(ld.lifetime),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
cx.path_all(span,
|
cx.path_all(span,
|
||||||
|
@ -226,11 +233,9 @@ fn mk_ty_param(cx: &ExtCtxt,
|
||||||
cx.typaram(span, cx.ident_of(name), attrs.to_owned(), bounds, None)
|
cx.typaram(span, cx.ident_of(name), attrs.to_owned(), bounds, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam>, span: Span)
|
fn mk_generics(params: Vec<GenericParam>, span: Span) -> Generics {
|
||||||
-> Generics {
|
|
||||||
Generics {
|
Generics {
|
||||||
lifetimes,
|
params,
|
||||||
ty_params,
|
|
||||||
where_clause: ast::WhereClause {
|
where_clause: ast::WhereClause {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
predicates: Vec::new(),
|
predicates: Vec::new(),
|
||||||
|
@ -260,26 +265,26 @@ impl<'a> LifetimeBounds<'a> {
|
||||||
self_ty: Ident,
|
self_ty: Ident,
|
||||||
self_generics: &Generics)
|
self_generics: &Generics)
|
||||||
-> Generics {
|
-> Generics {
|
||||||
let lifetimes = self.lifetimes
|
let generic_params = self.lifetimes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(lt, ref bounds)| {
|
.map(|&(lt, ref bounds)| {
|
||||||
let bounds = bounds.iter()
|
let bounds = bounds.iter()
|
||||||
.map(|b| cx.lifetime(span, Ident::from_str(b)))
|
.map(|b| cx.lifetime(span, Ident::from_str(b)))
|
||||||
.collect();
|
.collect();
|
||||||
cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds)
|
GenericParam::Lifetime(cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds))
|
||||||
})
|
})
|
||||||
.collect();
|
.chain(self.bounds
|
||||||
let ty_params = self.bounds
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| {
|
.map(|t| {
|
||||||
match *t {
|
let (name, ref bounds) = *t;
|
||||||
(ref name, ref bounds) => {
|
GenericParam::Type(mk_ty_param(
|
||||||
mk_ty_param(cx, span, *name, &[], bounds, self_ty, self_generics)
|
cx, span, name, &[], &bounds, self_ty, self_generics
|
||||||
}
|
))
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
)
|
||||||
.collect();
|
.collect();
|
||||||
mk_generics(lifetimes, ty_params, span)
|
|
||||||
|
mk_generics(generic_params, span)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,12 +121,14 @@ fn hygienic_type_parameter(item: &Annotatable, base: &str) -> String {
|
||||||
let mut typaram = String::from(base);
|
let mut typaram = String::from(base);
|
||||||
if let Annotatable::Item(ref item) = *item {
|
if let Annotatable::Item(ref item) = *item {
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::ItemKind::Struct(_, ast::Generics { ref ty_params, .. }) |
|
ast::ItemKind::Struct(_, ast::Generics { ref params, .. }) |
|
||||||
ast::ItemKind::Enum(_, ast::Generics { ref ty_params, .. }) => {
|
ast::ItemKind::Enum(_, ast::Generics { ref params, .. }) => {
|
||||||
for ty in ty_params.iter() {
|
for param in params.iter() {
|
||||||
|
if let ast::GenericParam::Type(ref ty) = *param{
|
||||||
typaram.push_str(&ty.ident.name.as_str());
|
typaram.push_str(&ty.ident.name.as_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,9 +89,9 @@ error[E0309]: the parameter type `T` may not live long enough
|
||||||
56 | with_signature(cell, t, |cell, t| require(cell, t));
|
56 | with_signature(cell, t, |cell, t| require(cell, t));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:17), 'a))`...
|
= help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`...
|
||||||
|
|
||||||
error: free region `ReEarlyBound(0, 'b)` does not outlive free region `ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:17), 'a))`
|
error: free region `ReEarlyBound(0, 'b)` does not outlive free region `ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`
|
||||||
--> $DIR/projection-one-region-closure.rs:56:20
|
--> $DIR/projection-one-region-closure.rs:56:20
|
||||||
|
|
|
|
||||||
56 | with_signature(cell, t, |cell, t| require(cell, t));
|
56 | with_signature(cell, t, |cell, t| require(cell, t));
|
||||||
|
|
|
@ -94,7 +94,7 @@ note: External requirements
|
||||||
= note: number of external vids: 3
|
= note: number of external vids: 3
|
||||||
= note: where '_#1r: '_#2r
|
= note: where '_#1r: '_#2r
|
||||||
|
|
||||||
error: free region `ReEarlyBound(0, 'b)` does not outlive free region `ReFree(DefId(0/0:8 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:17), 'a))`
|
error: free region `ReEarlyBound(0, 'b)` does not outlive free region `ReFree(DefId(0/0:8 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`
|
||||||
--> $DIR/projection-one-region-trait-bound-closure.rs:48:20
|
--> $DIR/projection-one-region-trait-bound-closure.rs:48:20
|
||||||
|
|
|
|
||||||
48 | with_signature(cell, t, |cell, t| require(cell, t));
|
48 | with_signature(cell, t, |cell, t| require(cell, t));
|
||||||
|
|
|
@ -158,7 +158,7 @@ error[E0309]: the associated type `<T as Anything<'_#5r, '_#6r>>::AssocType` may
|
||||||
49 | with_signature(cell, t, |cell, t| require(cell, t));
|
49 | with_signature(cell, t, |cell, t| require(cell, t));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider adding an explicit lifetime bound `<T as Anything<'_#5r, '_#6r>>::AssocType: ReFree(DefId(0/0:8 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:19), 'a))`...
|
= help: consider adding an explicit lifetime bound `<T as Anything<'_#5r, '_#6r>>::AssocType: ReFree(DefId(0/0:8 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:18), 'a))`...
|
||||||
|
|
||||||
note: No external requirements
|
note: No external requirements
|
||||||
--> $DIR/projection-two-region-trait-bound-closure.rs:45:1
|
--> $DIR/projection-two-region-trait-bound-closure.rs:45:1
|
||||||
|
@ -270,7 +270,7 @@ note: No external requirements
|
||||||
T
|
T
|
||||||
]
|
]
|
||||||
|
|
||||||
error: free region `ReEarlyBound(0, 'b)` does not outlive free region `ReFree(DefId(0/0:13 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]), BrNamed(crate0:DefIndex(1:44), 'a))`
|
error: free region `ReEarlyBound(0, 'b)` does not outlive free region `ReFree(DefId(0/0:13 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]), BrNamed(crate0:DefIndex(1:43), 'a))`
|
||||||
--> $DIR/projection-two-region-trait-bound-closure.rs:109:20
|
--> $DIR/projection-two-region-trait-bound-closure.rs:109:20
|
||||||
|
|
|
|
||||||
109 | with_signature(cell, t, |cell, t| require(cell, t));
|
109 | with_signature(cell, t, |cell, t| require(cell, t));
|
||||||
|
|
|
@ -66,7 +66,7 @@ error[E0309]: the parameter type `T` may not live long enough
|
||||||
43 | twice(cell, value, |a, b| invoke(a, b));
|
43 | twice(cell, value, |a, b| invoke(a, b));
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:6 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]), BrNamed(crate0:DefIndex(1:16), 'a))`...
|
= help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:6 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]), BrNamed(crate0:DefIndex(1:15), 'a))`...
|
||||||
|
|
||||||
note: No external requirements
|
note: No external requirements
|
||||||
--> $DIR/ty-param-closure-approximate-lower-bound.rs:42:1
|
--> $DIR/ty-param-closure-approximate-lower-bound.rs:42:1
|
||||||
|
|
|
@ -107,7 +107,7 @@ error[E0309]: the parameter type `T` may not live long enough
|
||||||
47 | | })
|
47 | | })
|
||||||
| |_____^
|
| |_____^
|
||||||
|
|
|
|
||||||
= help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:6 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]), BrNamed(crate0:DefIndex(1:15), 'a))`...
|
= help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:6 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]), BrNamed(crate0:DefIndex(1:14), 'a))`...
|
||||||
|
|
||||||
note: No external requirements
|
note: No external requirements
|
||||||
--> $DIR/ty-param-closure-outlives-from-where-clause.rs:37:1
|
--> $DIR/ty-param-closure-outlives-from-where-clause.rs:37:1
|
||||||
|
@ -154,7 +154,7 @@ error[E0309]: the parameter type `T` may not live long enough
|
||||||
81 | | })
|
81 | | })
|
||||||
| |_____^
|
| |_____^
|
||||||
|
|
|
|
||||||
= help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]), BrNamed(crate0:DefIndex(1:21), 'a))`...
|
= help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]), BrNamed(crate0:DefIndex(1:20), 'a))`...
|
||||||
|
|
||||||
note: No external requirements
|
note: No external requirements
|
||||||
--> $DIR/ty-param-closure-outlives-from-where-clause.rs:72:1
|
--> $DIR/ty-param-closure-outlives-from-where-clause.rs:72:1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue