Auto merge of #45930 - jplatte:generics_refactoring, r=eddyb
Generics refactoring (groundwork for const generics) These changes were suggested by @eddyb. After this change, the `Generics` contain one `Vec` of an enum for the generic parameters, rather than two separate `Vec`s for lifetime and type parameters. Type params and const params will need to be in a shared `Vec` to preserve their ordering, and moving lifetimes into the same `Vec` should simplify the code that processes `Generics`.
This commit is contained in:
commit
250b492052
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);
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
walk_list!(visitor, visit_lifetime_def, &generics.lifetimes);
|
}
|
||||||
|
|
||||||
|
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(
|
||||||
this.collect_in_band_defs(parent_id, |this| {
|
&generics.params
|
||||||
(this.lower_generics(generics), f(this))
|
.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.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,14 +1087,16 @@ 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 {
|
||||||
// Introduce lifetimes one at a time so that we can handle
|
if let hir::GenericParam::Lifetime(ref lt_def) = *param {
|
||||||
// cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`
|
// Introduce lifetimes one at a time so that we can handle
|
||||||
self.currently_bound_lifetimes.push(lt_def.lifetime.name);
|
// cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`
|
||||||
|
self.currently_bound_lifetimes.push(lt_def.lifetime.name);
|
||||||
|
|
||||||
// Visit the lifetime bounds
|
// Visit the lifetime bounds
|
||||||
for lt_bound in <_def.bounds {
|
for lt_bound in <_def.bounds {
|
||||||
self.visit_lifetime(<_bound);
|
self.visit_lifetime(<_bound);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,17 +1663,20 @@ 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 node_id == ty_param.id {
|
if let GenericParam::Type(ref ty_param) = *param {
|
||||||
add_bounds.entry(ty_param.id).or_insert(Vec::new())
|
if node_id == ty_param.id {
|
||||||
.push(bound.clone());
|
add_bounds.entry(ty_param.id)
|
||||||
continue 'next_bound;
|
.or_insert(Vec::new())
|
||||||
|
.push(bound.clone());
|
||||||
|
continue 'next_bound;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,24 +1709,33 @@ 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(
|
||||||
hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
|
&bound_generic_params.iter()
|
||||||
bound_lifetimes: this.lower_lifetime_defs(bound_lifetimes),
|
.filter_map(|p| match *p {
|
||||||
bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::Disallowed),
|
GenericParam::Lifetime(ref ld) => Some(ld.clone()),
|
||||||
bounds: bounds.iter().filter_map(|bound| match *bound {
|
_ => None,
|
||||||
// Ignore `?Trait` bounds.
|
})
|
||||||
// Tthey were copied into type parameters already.
|
.collect::<Vec<_>>(),
|
||||||
TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
|
|this| {
|
||||||
_ => Some(this.lower_ty_param_bound(
|
hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
|
||||||
bound, ImplTraitContext::Disallowed))
|
bound_generic_params:
|
||||||
}).collect(),
|
this.lower_generic_params(bound_generic_params, &NodeMap()),
|
||||||
span,
|
bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::Disallowed),
|
||||||
})
|
bounds: bounds.iter().filter_map(|bound| match *bound {
|
||||||
})
|
// Ignore `?Trait` bounds.
|
||||||
|
// Tthey were copied into type parameters already.
|
||||||
|
TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
|
||||||
|
_ => Some(this.lower_ty_param_bound(
|
||||||
|
bound, ImplTraitContext::Disallowed))
|
||||||
|
}).collect(),
|
||||||
|
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
|
||||||
impl_items.iter()
|
.iter()
|
||||||
.map(|item| this.lower_impl_item_ref(item))
|
.filter_map(|p| match *p {
|
||||||
.collect()
|
GenericParam::Lifetime(ref ld) => Some(ld.clone()),
|
||||||
});
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
|this| {
|
||||||
|
impl_items.iter()
|
||||||
|
.map(|item| this.lower_impl_item_ref(item))
|
||||||
|
.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) => {
|
||||||
DefPathData::TypeParam(ty_param.ident.name.as_str()),
|
self.create_def(
|
||||||
REGULAR_SPACE);
|
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()),
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GenericParam::Type(ref t) => {
|
||||||
|
if t.pure_wrt_drop {
|
||||||
|
return Some(UnsafeGeneric::Type(t.clone(), "may_dangle"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for t in &self.ty_params {
|
|
||||||
if t.pure_wrt_drop {
|
None
|
||||||
return Some(UnsafeGeneric::Type(t.clone(), "may_dangle"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 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 {
|
self.s.word("<")?;
|
||||||
return Ok(());
|
|
||||||
|
self.commasep(Inconsistent, generic_params, |s, param| {
|
||||||
|
match *param {
|
||||||
|
hir::GenericParam::Lifetime(ref ld) => s.print_lifetime_def(ld),
|
||||||
|
hir::GenericParam::Type(ref tp) => s.print_ty_param(tp),
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.s.word(">")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.s.word("<")?;
|
|
||||||
|
|
||||||
let mut ints = Vec::new();
|
|
||||||
for i in 0..total {
|
|
||||||
ints.push(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
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(">")?;
|
|
||||||
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 bounded_ty,
|
ref bound_generic_params,
|
||||||
ref bounds,
|
ref bounded_ty,
|
||||||
..}) => {
|
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() {
|
|
||||||
walk_list!(
|
for param in &generics.params {
|
||||||
&mut appears_in_where_clause,
|
match *param {
|
||||||
visit_ty_param_bound,
|
hir::GenericParam::Lifetime(ref lifetime_def) => {
|
||||||
&ty_param.bounds
|
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!(
|
||||||
|
&mut appears_in_where_clause,
|
||||||
|
visit_ty_param_bound,
|
||||||
|
&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,17 +283,25 @@ 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 !bounds.is_empty() {
|
if let GenericParam::Type(TyParam {
|
||||||
self.err_handler().span_err(span,
|
ref bounds,
|
||||||
"type parameters on the left side of a \
|
ref default,
|
||||||
trait alias cannot be bounded");
|
span,
|
||||||
}
|
..
|
||||||
if !default.is_none() {
|
}) = *param
|
||||||
self.err_handler().span_err(span,
|
{
|
||||||
"type parameters on the left side of a \
|
if !bounds.is_empty() {
|
||||||
trait alias cannot have defaults");
|
self.err_handler().span_err(span,
|
||||||
|
"type parameters on the left side of a \
|
||||||
|
trait alias cannot be bounded");
|
||||||
|
}
|
||||||
|
if !default.is_none() {
|
||||||
|
self.err_handler().span_err(span,
|
||||||
|
"type parameters on the left side of a \
|
||||||
|
trait alias cannot have defaults");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
self.visit_ty_param_bound(bound);
|
GenericParam::Lifetime(_) => self.visit_generic_param(param),
|
||||||
}
|
GenericParam::Type(ref ty_param) => {
|
||||||
|
for bound in &ty_param.bounds {
|
||||||
|
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,23 +2027,27 @@ 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 {
|
||||||
let ident = type_parameter.ident.modern();
|
if let GenericParam::Type(ref type_parameter) = *param {
|
||||||
debug!("with_type_parameter_rib: {}", type_parameter.id);
|
let ident = type_parameter.ident.modern();
|
||||||
|
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,
|
||||||
resolve_error(self, type_parameter.span, err);
|
span,
|
||||||
|
);
|
||||||
|
resolve_error(self, type_parameter.span, err);
|
||||||
|
}
|
||||||
|
seen_bindings.entry(ident).or_insert(type_parameter.span);
|
||||||
|
|
||||||
|
// plain insert (no renaming)
|
||||||
|
let def_id = self.definitions.local_def_id(type_parameter.id);
|
||||||
|
let def = Def::TyParam(def_id);
|
||||||
|
function_type_rib.bindings.insert(ident, def);
|
||||||
|
self.record_def(type_parameter.id, PathResolution::new(def));
|
||||||
}
|
}
|
||||||
seen_bindings.entry(ident).or_insert(type_parameter.span);
|
|
||||||
|
|
||||||
// plain insert (no renaming)
|
|
||||||
let def_id = self.definitions.local_def_id(type_parameter.id);
|
|
||||||
let def = Def::TyParam(def_id);
|
|
||||||
function_type_rib.bindings.insert(ident, def);
|
|
||||||
self.record_def(type_parameter.id, PathResolution::new(def));
|
|
||||||
}
|
}
|
||||||
self.ribs[TypeNS].push(function_type_rib);
|
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,35 +443,37 @@ 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 name = escape(self.span.snippet(param_ss));
|
let param_ss = ty_param.span;
|
||||||
// Append $id to name to make sure each one is unique
|
let name = escape(self.span.snippet(param_ss));
|
||||||
let qualname = format!("{}::{}${}", prefix, name, id);
|
// Append $id to name to make sure each one is unique
|
||||||
if !self.span.filter_generated(Some(param_ss), full_span) {
|
let qualname = format!("{}::{}${}", prefix, name, id);
|
||||||
let id = ::id_from_node_id(param.id, &self.save_ctxt);
|
if !self.span.filter_generated(Some(param_ss), full_span) {
|
||||||
let span = self.span_from_span(param_ss);
|
let id = ::id_from_node_id(ty_param.id, &self.save_ctxt);
|
||||||
|
let span = self.span_from_span(param_ss);
|
||||||
|
|
||||||
self.dumper.dump_def(
|
self.dumper.dump_def(
|
||||||
&Access {
|
&Access {
|
||||||
public: false,
|
public: false,
|
||||||
reachable: false,
|
reachable: false,
|
||||||
},
|
},
|
||||||
Def {
|
Def {
|
||||||
kind: DefKind::Type,
|
kind: DefKind::Type,
|
||||||
id,
|
id,
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
qualname,
|
qualname,
|
||||||
value: String::new(),
|
value: String::new(),
|
||||||
parent: None,
|
parent: None,
|
||||||
children: vec![],
|
children: vec![],
|
||||||
decl_id: None,
|
decl_id: None,
|
||||||
docs: String::new(),
|
docs: String::new(),
|
||||||
sig: None,
|
sig: None,
|
||||||
attributes: vec![],
|
attributes: vec![],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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,14 +1485,16 @@ 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 {
|
||||||
if let ast::TraitTyParamBound(ref trait_ref, _) = *bound {
|
for bound in ty_param.bounds.iter() {
|
||||||
self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
|
if let ast::TraitTyParamBound(ref trait_ref, _) = *bound {
|
||||||
|
self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(ref ty) = ty_param.default {
|
||||||
|
self.visit_ty(&ty);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if let Some(ref ty) = param.default {
|
|
||||||
self.visit_ty(&ty);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,50 +620,53 @@ 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 {
|
||||||
let mut l_text = l.lifetime.ident.to_string();
|
match *param {
|
||||||
defs.push(SigElement {
|
ast::GenericParam::Lifetime(ref l) => {
|
||||||
id: id_from_node_id(l.lifetime.id, scx),
|
let mut l_text = l.lifetime.ident.to_string();
|
||||||
start: offset + text.len(),
|
defs.push(SigElement {
|
||||||
end: offset + text.len() + l_text.len(),
|
id: id_from_node_id(l.lifetime.id, scx),
|
||||||
});
|
start: offset + text.len(),
|
||||||
|
end: offset + text.len() + l_text.len(),
|
||||||
|
});
|
||||||
|
|
||||||
if !l.bounds.is_empty() {
|
if !l.bounds.is_empty() {
|
||||||
l_text.push_str(": ");
|
l_text.push_str(": ");
|
||||||
let bounds = l.bounds
|
let bounds = l.bounds
|
||||||
.iter()
|
.iter()
|
||||||
.map(|l| l.ident.to_string())
|
.map(|l| l.ident.to_string())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(" + ");
|
.join(" + ");
|
||||||
l_text.push_str(&bounds);
|
l_text.push_str(&bounds);
|
||||||
// FIXME add lifetime bounds refs.
|
// FIXME add lifetime bounds refs.
|
||||||
}
|
}
|
||||||
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),
|
||||||
start: offset + text.len(),
|
start: offset + text.len(),
|
||||||
end: offset + text.len() + t_text.len(),
|
end: offset + text.len() + t_text.len(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if !t.bounds.is_empty() {
|
if !t.bounds.is_empty() {
|
||||||
t_text.push_str(": ");
|
t_text.push_str(": ");
|
||||||
t_text.push_str(&pprust::bounds_to_string(&t.bounds));
|
t_text.push_str(&pprust::bounds_to_string(&t.bounds));
|
||||||
// FIXME descend properly into bounds.
|
// FIXME descend properly into bounds.
|
||||||
|
}
|
||||||
|
text.push_str(&t_text);
|
||||||
|
text.push(',');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
text.push_str(&t_text);
|
|
||||||
text.push(',');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
text.push('>');
|
text.push('>');
|
||||||
|
|
|
@ -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,10 +1222,12 @@ 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 {
|
||||||
break
|
mem::swap(bounds, &mut type_param.bounds);
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,15 +139,22 @@ impl fmt::Display for clean::Generics {
|
||||||
} else {
|
} else {
|
||||||
write!(f, " = {}", ty)?;
|
write!(f, " = {}", ty)?;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
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() {
|
if f.alternate() {
|
||||||
f.write_str(">")?;
|
write!(f, "<{:#}>", CommaSep(&self.params))
|
||||||
} else {
|
} else {
|
||||||
f.write_str(">")?;
|
write!(f, "<{}>", CommaSep(&self.params))
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,8 +1424,10 @@ 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 {
|
||||||
self.typarams.insert(typ.did, typ.name.clone());
|
if let clean::GenericParam::Type(ref typ) = *param {
|
||||||
|
self.typarams.insert(typ.did, typ.name.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -301,30 +301,56 @@ 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 t.ident.name == name {
|
if let GenericParam::Type(ref t) = *param {
|
||||||
return Some(t.span);
|
if t.ident.name == name {
|
||||||
|
return Some(t.span);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -335,8 +361,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(),
|
||||||
|
@ -372,8 +397,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`)
|
||||||
|
@ -1461,7 +1486,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>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1820,7 +1845,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,
|
||||||
|
@ -1829,9 +1854,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)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_lifetime_def(&mut self, lifetime_def: &'a ast::LifetimeDef) {
|
if !attrs.is_empty() {
|
||||||
if !lifetime_def.attrs.is_empty() {
|
gate_feature_post!(&self, generic_param_attrs, attrs[0].span, explain);
|
||||||
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)
|
|
||||||
|
visit::walk_generic_param(self, param)
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -1299,7 +1300,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> {
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -1331,7 +1332,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,
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
@ -1621,9 +1622,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(); // `+`
|
||||||
|
@ -4590,9 +4591,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()?;
|
||||||
|
@ -4604,18 +4604,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.
|
||||||
|
@ -4631,7 +4631,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
|
||||||
|
@ -4646,11 +4646,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(),
|
||||||
|
@ -4778,7 +4777,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,
|
||||||
}
|
}
|
||||||
|
@ -5403,16 +5402,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) => {
|
||||||
}
|
s.print_outer_attributes_inline(&lifetime_def.attrs)?;
|
||||||
|
s.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds)
|
||||||
self.commasep(Inconsistent, &ints[..], |s, &idx| {
|
},
|
||||||
if idx < generics.lifetimes.len() {
|
ast::GenericParam::Type(ref ty_param) => s.print_ty_param(ty_param),
|
||||||
let lifetime_def = &generics.lifetimes[idx];
|
|
||||||
s.print_outer_attributes_inline(&lifetime_def.attrs)?;
|
|
||||||
s.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds)
|
|
||||||
} else {
|
|
||||||
let idx = idx - generics.lifetimes.len();
|
|
||||||
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 bounded_ty,
|
ref bound_generic_params,
|
||||||
ref bounds,
|
ref bounded_ty,
|
||||||
..}) => {
|
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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
walk_list!(visitor, visit_lifetime_def, &generics.lifetimes);
|
}
|
||||||
|
|
||||||
|
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![];
|
{
|
||||||
is_shallow = true;
|
bounds = vec![];
|
||||||
substructure = combine_substructure(Box::new(|c, s, sub| {
|
is_shallow = true;
|
||||||
cs_clone_shallow("Clone", c, s, sub, false)
|
substructure = combine_substructure(Box::new(|c, s, sub| {
|
||||||
}));
|
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,32 +539,35 @@ 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 {
|
||||||
|
ref l @ GenericParam::Lifetime(_) => l.clone(),
|
||||||
|
GenericParam::Type(ref ty_param) => {
|
||||||
|
// I don't think this can be moved out of the loop, since
|
||||||
|
// a TyParamBound requires an ast id
|
||||||
|
let mut bounds: Vec<_> =
|
||||||
|
// extra restrictions on the generics parameters to the
|
||||||
|
// type being derived upon
|
||||||
|
self.additional_bounds.iter().map(|p| {
|
||||||
|
cx.typarambound(p.to_path(cx, self.span,
|
||||||
|
type_ident, generics))
|
||||||
|
}).collect();
|
||||||
|
|
||||||
// Create the type parameters.
|
// require the current trait
|
||||||
ty_params.extend(generics.ty_params.iter().map(|ty_param| {
|
bounds.push(cx.typarambound(trait_path.clone()));
|
||||||
// I don't think this can be moved out of the loop, since
|
|
||||||
// a TyParamBound requires an ast id
|
|
||||||
let mut bounds: Vec<_> =
|
|
||||||
// extra restrictions on the generics parameters to the type being derived upon
|
|
||||||
self.additional_bounds.iter().map(|p| {
|
|
||||||
cx.typarambound(p.to_path(cx, self.span,
|
|
||||||
type_ident, generics))
|
|
||||||
}).collect();
|
|
||||||
|
|
||||||
// require the current trait
|
// also add in any bounds from the declaration
|
||||||
bounds.push(cx.typarambound(trait_path.clone()));
|
for declared_bound in ty_param.bounds.iter() {
|
||||||
|
bounds.push((*declared_bound).clone());
|
||||||
|
}
|
||||||
|
|
||||||
// also add in any bounds from the declaration
|
GenericParam::Type(cx.typaram(self.span, ty_param.ident, vec![], bounds, None))
|
||||||
for declared_bound in ty_param.bounds.iter() {
|
}
|
||||||
bounds.push((*declared_bound).clone());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,49 +599,61 @@ 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
|
||||||
.map(|ty_param| ty_param.ident.name)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut processed_field_types = HashSet::new();
|
let mut ty_params = params.iter()
|
||||||
for field_ty in field_tys {
|
.filter_map(|param| match *param {
|
||||||
let tys = find_type_parameters(&field_ty, &ty_param_names, self.span, cx);
|
ast::GenericParam::Type(ref t) => Some(t),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.peekable();
|
||||||
|
|
||||||
for ty in tys {
|
if ty_params.peek().is_some() {
|
||||||
// if we have already handled this type, skip it
|
let ty_param_names: Vec<ast::Name> = ty_params
|
||||||
if let ast::TyKind::Path(_, ref p) = ty.node {
|
.map(|ty_param| ty_param.ident.name)
|
||||||
if p.segments.len() == 1 &&
|
.collect();
|
||||||
ty_param_names.contains(&p.segments[0].identifier.name) ||
|
|
||||||
processed_field_types.contains(&p.segments) {
|
let mut processed_field_types = HashSet::new();
|
||||||
continue;
|
for field_ty in field_tys {
|
||||||
|
let tys = find_type_parameters(&field_ty, &ty_param_names, self.span, cx);
|
||||||
|
|
||||||
|
for ty in tys {
|
||||||
|
// if we have already handled this type, skip it
|
||||||
|
if let ast::TyKind::Path(_, ref p) = ty.node {
|
||||||
|
if p.segments.len() == 1 &&
|
||||||
|
ty_param_names.contains(&p.segments[0].identifier.name) ||
|
||||||
|
processed_field_types.contains(&p.segments) {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
processed_field_types.insert(p.segments.clone());
|
||||||
|
}
|
||||||
|
let mut bounds: Vec<_> = self.additional_bounds
|
||||||
|
.iter()
|
||||||
|
.map(|p| {
|
||||||
|
cx.typarambound(p.to_path(cx, self.span, type_ident, generics))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// require the current trait
|
||||||
|
bounds.push(cx.typarambound(trait_path.clone()));
|
||||||
|
|
||||||
|
let predicate = ast::WhereBoundPredicate {
|
||||||
|
span: self.span,
|
||||||
|
bound_generic_params: Vec::new(),
|
||||||
|
bounded_ty: ty,
|
||||||
|
bounds,
|
||||||
};
|
};
|
||||||
processed_field_types.insert(p.segments.clone());
|
|
||||||
|
let predicate = ast::WherePredicate::BoundPredicate(predicate);
|
||||||
|
where_clause.predicates.push(predicate);
|
||||||
}
|
}
|
||||||
let mut bounds: Vec<_> = self.additional_bounds
|
|
||||||
.iter()
|
|
||||||
.map(|p| cx.typarambound(p.to_path(cx, self.span, type_ident, generics)))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// require the current trait
|
|
||||||
bounds.push(cx.typarambound(trait_path.clone()));
|
|
||||||
|
|
||||||
let predicate = ast::WhereBoundPredicate {
|
|
||||||
span: self.span,
|
|
||||||
bound_lifetimes: vec![],
|
|
||||||
bounded_ty: ty,
|
|
||||||
bounds,
|
|
||||||
};
|
|
||||||
|
|
||||||
let predicate = ast::WherePredicate::BoundPredicate(predicate);
|
|
||||||
where_clause.predicates.push(predicate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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))
|
||||||
})
|
})
|
||||||
|
.chain(self.bounds
|
||||||
|
.iter()
|
||||||
|
.map(|t| {
|
||||||
|
let (name, ref bounds) = *t;
|
||||||
|
GenericParam::Type(mk_ty_param(
|
||||||
|
cx, span, name, &[], &bounds, self_ty, self_generics
|
||||||
|
))
|
||||||
|
})
|
||||||
|
)
|
||||||
.collect();
|
.collect();
|
||||||
let ty_params = self.bounds
|
|
||||||
.iter()
|
mk_generics(generic_params, span)
|
||||||
.map(|t| {
|
|
||||||
match *t {
|
|
||||||
(ref name, ref bounds) => {
|
|
||||||
mk_ty_param(cx, span, *name, &[], bounds, self_ty, self_generics)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
mk_generics(lifetimes, ty_params, span)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,10 +121,12 @@ 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() {
|
||||||
typaram.push_str(&ty.ident.name.as_str());
|
if let ast::GenericParam::Type(ref ty) = *param{
|
||||||
|
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