Fn(FnCtxt, Ident, &'a FnSig, &'a Visibility, &'a Generics, Option<&'a Block>),
/// E.g., `|x, y| body`.
- Closure(&'a FnDecl, &'a Expr),
+ Closure(&'a ClosureBinder, &'a FnDecl, &'a Expr),
}
impl<'a> FnKind<'a> {
pub fn header(&self) -> Option<&'a FnHeader> {
match *self {
FnKind::Fn(_, _, sig, _, _, _) => Some(&sig.header),
- FnKind::Closure(_, _) => None,
+ FnKind::Closure(_, _, _) => None,
}
}
pub fn decl(&self) -> &'a FnDecl {
match self {
FnKind::Fn(_, _, sig, _, _, _) => &sig.decl,
- FnKind::Closure(decl, _) => decl,
+ FnKind::Closure(_, decl, _) => decl,
}
}
}
}
+#[derive(Copy, Clone, Debug)]
+pub enum LifetimeCtxt {
+ /// Appears in a reference type.
+ Rptr,
+ /// Appears as a bound on a type or another lifetime.
+ Bound,
+ /// Appears as a generic argument.
+ GenericArg,
+}
+
/// Each method of the `Visitor` trait is a hook to be potentially
/// overridden. Each method's default implementation recursively visits
/// the substructure of the input via the corresponding `walk` method;
fn visit_generics(&mut self, g: &'ast Generics) {
walk_generics(self, g)
}
+ fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) {
+ walk_closure_binder(self, b)
+ }
fn visit_where_predicate(&mut self, p: &'ast WherePredicate) {
walk_where_predicate(self, p)
}
fn visit_label(&mut self, label: &'ast Label) {
walk_label(self, label)
}
- fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) {
+ fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, _: LifetimeCtxt) {
walk_lifetime(self, lifetime)
}
fn visit_mac_call(&mut self, mac: &'ast MacCall) {
TyKind::Slice(ref ty) | TyKind::Paren(ref ty) => visitor.visit_ty(ty),
TyKind::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty),
TyKind::Rptr(ref opt_lifetime, ref mutable_type) => {
- walk_list!(visitor, visit_lifetime, opt_lifetime);
+ walk_list!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Rptr);
visitor.visit_ty(&mutable_type.ty)
}
TyKind::Tup(ref tuple_element_types) => {
V: Visitor<'a>,
{
match generic_arg {
- GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt),
+ GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg),
GenericArg::Type(ty) => visitor.visit_ty(ty),
GenericArg::Const(ct) => visitor.visit_anon_const(ct),
}
pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) {
match *bound {
GenericBound::Trait(ref typ, ref modifier) => visitor.visit_poly_trait_ref(typ, modifier),
- GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
+ GenericBound::Outlives(ref lifetime) => {
+ visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound)
+ }
}
}
walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates);
}
+pub fn walk_closure_binder<'a, V: Visitor<'a>>(visitor: &mut V, binder: &'a ClosureBinder) {
+ match binder {
+ ClosureBinder::NotPresent => {}
+ ClosureBinder::For { generic_params, span: _ } => {
+ walk_list!(visitor, visit_generic_param, generic_params)
+ }
+ }
+}
+
pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a WherePredicate) {
match *predicate {
WherePredicate::BoundPredicate(WhereBoundPredicate {
WherePredicate::RegionPredicate(WhereRegionPredicate {
ref lifetime, ref bounds, ..
}) => {
- visitor.visit_lifetime(lifetime);
+ visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound);
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
}
WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. }) => {
walk_fn_decl(visitor, &sig.decl);
walk_list!(visitor, visit_block, body);
}
- FnKind::Closure(decl, body) => {
+ FnKind::Closure(binder, decl, body) => {
+ visitor.visit_closure_binder(binder);
walk_fn_decl(visitor, decl);
visitor.visit_expr(body);
}
visitor.visit_expr(subexpression);
walk_list!(visitor, visit_arm, arms);
}
- ExprKind::Closure(_, _, _, ref decl, ref body, _decl_span) => {
- visitor.visit_fn(FnKind::Closure(decl, body), expression.span, expression.id)
+ ExprKind::Closure(ref binder, _, _, _, ref decl, ref body, _decl_span) => {
+ visitor.visit_fn(FnKind::Closure(binder, decl, body), expression.span, expression.id)
}
ExprKind::Block(ref block, ref opt_label) => {
walk_list!(visitor, visit_label, opt_label);