Skip to content

Commit

Permalink
auto merge of #17069 : eddyb/rust/visitor, r=pnkfelix
Browse files Browse the repository at this point in the history
Few visitors used the context passing feature and it can be easily emulated.
The added lifetime threading allows a visitor to keep safe references to AST
nodes it visits, making a non-owning ast_map design possible, for #13316.
  • Loading branch information
bors committed Sep 12, 2014
2 parents e9278c9 + 7ef6ff0 commit 9c68679
Show file tree
Hide file tree
Showing 49 changed files with 1,546 additions and 1,615 deletions.
53 changes: 26 additions & 27 deletions src/librustc/front/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,15 @@ impl<'a> Context<'a> {
}
}

impl<'a> Visitor<()> for Context<'a> {
fn visit_ident(&mut self, sp: Span, id: ast::Ident, _: ()) {
impl<'a, 'v> Visitor<'v> for Context<'a> {
fn visit_ident(&mut self, sp: Span, id: ast::Ident) {
if !token::get_ident(id).get().is_ascii() {
self.gate_feature("non_ascii_idents", sp,
"non-ascii idents are not fully supported.");
}
}

fn visit_view_item(&mut self, i: &ast::ViewItem, _: ()) {
fn visit_view_item(&mut self, i: &ast::ViewItem) {
match i.node {
ast::ViewItemUse(ref path) => {
match path.node {
Expand All @@ -173,10 +173,10 @@ impl<'a> Visitor<()> for Context<'a> {
}
}
}
visit::walk_view_item(self, i, ())
visit::walk_view_item(self, i)
}

fn visit_item(&mut self, i: &ast::Item, _:()) {
fn visit_item(&mut self, i: &ast::Item) {
for attr in i.attrs.iter() {
if attr.name().equiv(&("thread_local")) {
self.gate_feature("thread_local", i.span,
Expand Down Expand Up @@ -252,10 +252,10 @@ impl<'a> Visitor<()> for Context<'a> {
_ => {}
}

visit::walk_item(self, i, ());
visit::walk_item(self, i);
}

fn visit_mac(&mut self, macro: &ast::Mac, _: ()) {
fn visit_mac(&mut self, macro: &ast::Mac) {
let ast::MacInvocTT(ref path, _, _) = macro.node;
let id = path.segments.last().unwrap().identifier;
let quotes = ["quote_tokens", "quote_expr", "quote_ty",
Expand Down Expand Up @@ -299,16 +299,16 @@ impl<'a> Visitor<()> for Context<'a> {
}
}

fn visit_foreign_item(&mut self, i: &ast::ForeignItem, _: ()) {
fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
if attr::contains_name(i.attrs.as_slice(), "linkage") {
self.gate_feature("linkage", i.span,
"the `linkage` attribute is experimental \
and not portable across platforms")
}
visit::walk_foreign_item(self, i, ())
visit::walk_foreign_item(self, i)
}

fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
fn visit_ty(&mut self, t: &ast::Ty) {
match t.node {
ast::TyClosure(closure) if closure.onceness == ast::Once => {
self.gate_feature("once_fns", t.span,
Expand All @@ -325,10 +325,10 @@ impl<'a> Visitor<()> for Context<'a> {
_ => {}
}

visit::walk_ty(self, t, ());
visit::walk_ty(self, t);
}

fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
fn visit_expr(&mut self, e: &ast::Expr) {
match e.node {
ast::ExprUnary(ast::UnBox, _) => {
self.gate_box(e.span);
Expand All @@ -346,10 +346,10 @@ impl<'a> Visitor<()> for Context<'a> {
}
_ => {}
}
visit::walk_expr(self, e, ());
visit::walk_expr(self, e);
}

fn visit_generics(&mut self, generics: &ast::Generics, _: ()) {
fn visit_generics(&mut self, generics: &ast::Generics) {
for type_parameter in generics.ty_params.iter() {
match type_parameter.default {
Some(ty) => {
Expand All @@ -360,18 +360,18 @@ impl<'a> Visitor<()> for Context<'a> {
None => {}
}
}
visit::walk_generics(self, generics, ());
visit::walk_generics(self, generics);
}

fn visit_attribute(&mut self, attr: &ast::Attribute, _: ()) {
fn visit_attribute(&mut self, attr: &ast::Attribute) {
if attr::contains_name([*attr], "lang") {
self.gate_feature("lang_items",
attr.span,
"language items are subject to change");
}
}

fn visit_pat(&mut self, pattern: &ast::Pat, (): ()) {
fn visit_pat(&mut self, pattern: &ast::Pat) {
match pattern.node {
ast::PatVec(_, Some(_), ref last) if !last.is_empty() => {
self.gate_feature("advanced_slice_patterns",
Expand All @@ -382,25 +382,24 @@ impl<'a> Visitor<()> for Context<'a> {
}
_ => {}
}
visit::walk_pat(self, pattern, ())
visit::walk_pat(self, pattern)
}

fn visit_fn(&mut self,
fn_kind: &visit::FnKind,
fn_decl: &ast::FnDecl,
block: &ast::Block,
fn_kind: visit::FnKind<'v>,
fn_decl: &'v ast::FnDecl,
block: &'v ast::Block,
span: Span,
_: NodeId,
(): ()) {
match *fn_kind {
visit::FkItemFn(_, _, _, ref abi) if *abi == RustIntrinsic => {
_: NodeId) {
match fn_kind {
visit::FkItemFn(_, _, _, abi) if abi == RustIntrinsic => {
self.gate_feature("intrinsics",
span,
"intrinsics are subject to change")
}
_ => {}
}
visit::walk_fn(self, fn_kind, fn_decl, block, span, ());
visit::walk_fn(self, fn_kind, fn_decl, block, span);
}
}

Expand Down Expand Up @@ -453,7 +452,7 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) {
}
}

visit::walk_crate(&mut cx, krate, ());
visit::walk_crate(&mut cx, krate);

sess.abort_if_errors();

Expand Down
12 changes: 6 additions & 6 deletions src/librustc/front/show_span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ struct ShowSpanVisitor<'a> {
sess: &'a Session
}

impl<'a> Visitor<()> for ShowSpanVisitor<'a> {
fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
impl<'a, 'v> Visitor<'v> for ShowSpanVisitor<'a> {
fn visit_expr(&mut self, e: &ast::Expr) {
self.sess.span_note(e.span, "expression");
visit::walk_expr(self, e, ());
visit::walk_expr(self, e);
}

fn visit_mac(&mut self, macro: &ast::Mac, e: ()) {
visit::walk_mac(self, macro, e);
fn visit_mac(&mut self, macro: &ast::Mac) {
visit::walk_mac(self, macro);
}
}

pub fn run(sess: &Session, krate: &ast::Crate) {
let mut v = ShowSpanVisitor { sess: sess };
visit::walk_crate(&mut v, krate, ());
visit::walk_crate(&mut v, krate);
}
30 changes: 15 additions & 15 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,13 +366,13 @@ impl<'a, 'tcx> CTypesVisitor<'a, 'tcx> {
}
}

impl<'a, 'tcx> Visitor<()> for CTypesVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for CTypesVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node {
ast::TyPath(_, _, id) => self.check_def(ty.span, ty.id, id),
_ => (),
}
visit::walk_ty(self, ty, ());
visit::walk_ty(self, ty);
}
}

Expand All @@ -386,7 +386,7 @@ impl LintPass for CTypes {
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
fn check_ty(cx: &Context, ty: &ast::Ty) {
let mut vis = CTypesVisitor { cx: cx };
vis.visit_ty(ty, ());
vis.visit_ty(ty);
}

fn check_foreign_fn(cx: &Context, decl: &ast::FnDecl) {
Expand Down Expand Up @@ -500,18 +500,18 @@ struct RawPtrDerivingVisitor<'a, 'tcx: 'a> {
cx: &'a Context<'a, 'tcx>
}

impl<'a, 'tcx> Visitor<()> for RawPtrDerivingVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for RawPtrDerivingVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) {
static MSG: &'static str = "use of `#[deriving]` with a raw pointer";
match ty.node {
ast::TyPtr(..) => self.cx.span_lint(RAW_POINTER_DERIVING, ty.span, MSG),
_ => {}
}
visit::walk_ty(self, ty, ());
visit::walk_ty(self, ty);
}
// explicit override to a no-op to reduce code bloat
fn visit_expr(&mut self, _: &ast::Expr, _: ()) {}
fn visit_block(&mut self, _: &ast::Block, _: ()) {}
fn visit_expr(&mut self, _: &ast::Expr) {}
fn visit_block(&mut self, _: &ast::Block) {}
}

pub struct RawPointerDeriving {
Expand Down Expand Up @@ -554,7 +554,7 @@ impl LintPass for RawPointerDeriving {
match item.node {
ast::ItemStruct(..) | ast::ItemEnum(..) => {
let mut visitor = RawPtrDerivingVisitor { cx: cx };
visit::walk_item(&mut visitor, &*item, ());
visit::walk_item(&mut visitor, &*item);
}
_ => {}
}
Expand Down Expand Up @@ -908,9 +908,9 @@ impl LintPass for NonSnakeCase {
}

fn check_fn(&mut self, cx: &Context,
fk: &visit::FnKind, _: &ast::FnDecl,
fk: visit::FnKind, _: &ast::FnDecl,
_: &ast::Block, span: Span, _: ast::NodeId) {
match *fk {
match fk {
visit::FkMethod(ident, _, m) => match method_context(cx, m) {
PlainImpl
=> self.check_snake_case(cx, "method", ident, span),
Expand Down Expand Up @@ -1218,7 +1218,7 @@ impl LintPass for UnusedMut {
}

fn check_fn(&mut self, cx: &Context,
_: &visit::FnKind, decl: &ast::FnDecl,
_: visit::FnKind, decl: &ast::FnDecl,
_: &ast::Block, _: Span, _: ast::NodeId) {
for a in decl.inputs.iter() {
self.check_unused_mut_pat(cx, &[a.pat]);
Expand Down Expand Up @@ -1387,9 +1387,9 @@ impl LintPass for MissingDoc {
}

fn check_fn(&mut self, cx: &Context,
fk: &visit::FnKind, _: &ast::FnDecl,
fk: visit::FnKind, _: &ast::FnDecl,
_: &ast::Block, _: Span, _: ast::NodeId) {
match *fk {
match fk {
visit::FkMethod(_, _, m) => {
// If the method is an impl for a trait, don't doc.
if method_context(cx, m) == TraitImpl { return; }
Expand Down

0 comments on commit 9c68679

Please sign in to comment.