X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_ast%2Fsrc%2Fvisit.rs;h=3f830acbf27a61f139fb4aa79f5edea564ba70e8;hb=c2dbd62c7c60cd4017c9d499101e40c129e4bc61;hp=42213cf69661b504dac2ef80db5adb7b4a8ec631;hpb=67a9bcb31b85e87cc8bb327022632e48a0ca64a8;p=rust.git diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 42213cf6966..3f830acbf27 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -56,14 +56,14 @@ pub enum FnKind<'a> { 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, } } @@ -77,7 +77,7 @@ pub fn ident(&self) -> Option<&Ident> { pub fn decl(&self) -> &'a FnDecl { match self { FnKind::Fn(_, _, sig, _, _, _) => &sig.decl, - FnKind::Closure(decl, _) => decl, + FnKind::Closure(_, decl, _) => decl, } } @@ -89,6 +89,16 @@ pub fn ctxt(&self) -> Option { } } +#[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; @@ -145,6 +155,9 @@ fn visit_generic_param(&mut self, param: &'ast GenericParam) { 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) } @@ -184,7 +197,7 @@ fn visit_variant(&mut self, v: &'ast Variant) { 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) { @@ -414,7 +427,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { 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) => { @@ -507,7 +520,7 @@ pub fn walk_generic_arg<'a, V>(visitor: &mut V, generic_arg: &'a GenericArg) 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), } @@ -599,7 +612,9 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI 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) + } } } @@ -624,6 +639,15 @@ pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics 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 { @@ -639,7 +663,7 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a 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, .. }) => { @@ -670,7 +694,8 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>, _span: Spa 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); } @@ -844,8 +869,8 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { 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);