提交 50e42ea9 编写于 作者: V Vadim Petrochenkov

Correctly walk import lists in AST visitors

上级 d3fc6e18
......@@ -100,7 +100,7 @@
#![cfg_attr(stage0, feature(alloc_system))]
#![cfg_attr(not(stage0), feature(needs_allocator))]
#![cfg_attr(test, feature(test, rustc_private))]
#![cfg_attr(test, feature(test, rustc_private, box_heap))]
#[cfg(stage0)]
extern crate alloc_system;
......
......@@ -38,6 +38,8 @@
#![feature(core_intrinsics)]
#![feature(core_slice_ext)]
#![feature(core_str_ext)]
#![feature(fmt_internals)]
#![feature(fmt_radix)]
#![feature(heap_api)]
#![feature(iter_order)]
#![feature(iter_arith)]
......@@ -47,6 +49,8 @@
#![feature(oom)]
#![feature(pattern)]
#![feature(ptr_as_ref)]
#![feature(ref_slice)]
#![feature(slice_bytes)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(step_by)]
......
......@@ -38,6 +38,7 @@
use boxed::Box;
pub use core::str::{FromStr, Utf8Error};
#[allow(deprecated)]
pub use core::str::{Lines, LinesAny, CharRange};
pub use core::str::{Split, RSplit};
pub use core::str::{SplitN, RSplitN};
......
......@@ -915,6 +915,11 @@ fn visit_path(&mut self, p: &ast::Path, id: ast::NodeId) {
ast_visit::walk_path(self, p);
}
fn visit_path_list_item(&mut self, prefix: &hir::Path, item: &hir::PathListItem) {
run_lints!(self, check_path_list_item, item);
visit::walk_path_list_item(self, prefix, item);
}
fn visit_attribute(&mut self, attr: &ast::Attribute) {
run_lints!(self, check_attribute, early_passes, attr);
}
......
......@@ -165,6 +165,7 @@ fn check_explicit_self(&mut self, _: &LateContext, _: &hir::ExplicitSelf) { }
// because then your lint will be called twice. Prefer check_ast_mac.
fn check_mac(&mut self, _: &LateContext, _: &ast::Mac) { }
fn check_path(&mut self, _: &LateContext, _: &hir::Path, _: ast::NodeId) { }
fn check_path_list_item(&mut self, _: &LateContext, _: &hir::PathListItem) { }
fn check_attribute(&mut self, _: &LateContext, _: &ast::Attribute) { }
/// Called when entering a syntax node that can have lint attributes such
......@@ -211,6 +212,7 @@ fn check_lifetime_def(&mut self, _: &EarlyContext, _: &ast::LifetimeDef) { }
fn check_explicit_self(&mut self, _: &EarlyContext, _: &ast::ExplicitSelf) { }
fn check_mac(&mut self, _: &EarlyContext, _: &ast::Mac) { }
fn check_path(&mut self, _: &EarlyContext, _: &ast::Path, _: ast::NodeId) { }
fn check_path_list_item(&mut self, _: &EarlyContext, _: &ast::PathListItem) { }
fn check_attribute(&mut self, _: &EarlyContext, _: &ast::Attribute) { }
/// Called when entering a syntax node that can have lint attributes such
......
......@@ -279,6 +279,11 @@ fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
visit::walk_path(self, path);
}
fn visit_path_list_item(&mut self, path: &hir::Path, item: &hir::PathListItem) {
self.lookup_and_handle_definition(&item.node.id());
visit::walk_path_list_item(self, path, item);
}
fn visit_item(&mut self, _: &hir::Item) {
// Do not recurse into items. These items will be added to the
// worklist and recursed into manually if necessary.
......
......@@ -355,6 +355,12 @@ fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
visit::walk_path(self, path)
}
fn visit_path_list_item(&mut self, prefix: &hir::Path, item: &hir::PathListItem) {
check_path_list_item(self.tcx, item,
&mut |id, sp, stab| self.check(id, sp, stab));
visit::walk_path_list_item(self, prefix, item)
}
fn visit_pat(&mut self, pat: &hir::Pat) {
check_pat(self.tcx, pat,
&mut |id, sp, stab| self.check(id, sp, stab));
......@@ -470,7 +476,17 @@ pub fn check_path(tcx: &ty::ctxt, path: &hir::Path, id: ast::NodeId,
}
None => {}
}
}
pub fn check_path_list_item(tcx: &ty::ctxt, item: &hir::PathListItem,
cb: &mut FnMut(DefId, Span, &Option<&Stability>)) {
match tcx.def_map.borrow().get(&item.node.id()).map(|d| d.full_def()) {
Some(def::DefPrimTy(..)) => {}
Some(def) => {
maybe_do_stability_check(tcx, def.def_id(), item.span, cb);
}
None => {}
}
}
pub fn check_pat(tcx: &ty::ctxt, pat: &hir::Pat,
......
......@@ -423,6 +423,10 @@ fn visit_path(&mut self, path: &Path, _: ast::NodeId) {
SawPath.hash(self.st); visit::walk_path(self, path)
}
fn visit_path_list_item(&mut self, prefix: &Path, item: &'v PathListItem) {
SawPath.hash(self.st); visit::walk_path_list_item(self, prefix, item)
}
fn visit_block(&mut self, b: &Block) {
SawBlock.hash(self.st); visit::walk_block(self, b)
}
......
......@@ -121,6 +121,9 @@ fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) {
fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
walk_path(self, path)
}
fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) {
walk_path_list_item(self, prefix, item)
}
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
walk_path_segment(self, path_span, path_segment)
}
......@@ -203,26 +206,21 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
ItemExternCrate(..) => {}
ItemUse(ref vp) => {
match vp.node {
ViewPathSimple(ident, ref path) => {
visitor.visit_ident(vp.span, ident);
ViewPathSimple(_ident, ref path) => {
visitor.visit_path(path, item.id);
}
ViewPathGlob(ref path) => {
visitor.visit_path(path, item.id);
}
ViewPathList(ref prefix, ref list) => {
for id in list {
match id.node {
PathListIdent { name, .. } => {
visitor.visit_ident(id.span, name);
}
PathListMod { .. } => ()
if !list.is_empty() {
for item in list {
visitor.visit_path_list_item(prefix, item)
}
} else {
// FIXME: uncomment this and fix the resulting ICE
// visitor.visit_path(prefix, item.id);
}
// Note that the `prefix` here is not a complete
// path, so we don't use `visit_path`.
walk_path(visitor, prefix);
}
}
}
......@@ -400,6 +398,17 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
}
}
pub fn walk_path_list_item<'v, V: Visitor<'v>>(visitor: &mut V, prefix: &'v Path,
item: &'v PathListItem) {
for segment in &prefix.segments {
visitor.visit_path_segment(prefix.span, segment);
}
if let PathListIdent { name, .. } = item.node {
visitor.visit_ident(item.span, name);
}
}
pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
path_span: Span,
segment: &'v PathSegment) {
......
......@@ -2173,6 +2173,13 @@ fn check_path(&mut self, cx: &LateContext, path: &hir::Path, id: ast::NodeId) {
&stab.map(|s| hir_to_ast_stability(s)).as_ref()));
}
fn check_path_list_item(&mut self, cx: &LateContext, item: &hir::PathListItem) {
stability::check_path_list_item(cx.tcx, item,
&mut |id, sp, stab|
self.lint(cx, id, sp,
&stab.map(|s| hir_to_ast_stability(s)).as_ref()));
}
fn check_pat(&mut self, cx: &LateContext, pat: &hir::Pat) {
stability::check_pat(cx.tcx, pat,
&mut |id, sp, stab|
......
......@@ -859,23 +859,6 @@ fn check_method(&mut self, span: Span, method_def_id: DefId,
impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &hir::Item) {
if let hir::ItemUse(ref vpath) = item.node {
if let hir::ViewPathList(ref prefix, ref list) = vpath.node {
for pid in list {
match pid.node {
hir::PathListIdent { id, name, .. } => {
debug!("privacy - ident item {}", id);
self.check_path(pid.span, id, name.name);
}
hir::PathListMod { id, .. } => {
debug!("privacy - mod item {}", id);
let name = prefix.segments.last().unwrap().identifier.name;
self.check_path(pid.span, id, name);
}
}
}
}
}
let orig_curitem = replace(&mut self.curitem, item.id);
visit::walk_item(self, item);
self.curitem = orig_curitem;
......@@ -1000,6 +983,16 @@ fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
self.check_path(path.span, id, path.segments.last().unwrap().identifier.name);
visit::walk_path(self, path);
}
fn visit_path_list_item(&mut self, prefix: &hir::Path, item: &hir::PathListItem) {
let name = if let hir::PathListIdent { name, .. } = item.node {
name.name
} else {
prefix.segments.last().unwrap().identifier.name
};
self.check_path(item.span, item.node.id(), name);
visit::walk_path_list_item(self, prefix, item);
}
}
////////////////////////////////////////////////////////////////////////////////
......
......@@ -201,6 +201,7 @@
#![feature(alloc)]
#![feature(allow_internal_unstable)]
#![feature(arc_weak)]
#![feature(associated_consts)]
#![feature(borrow_state)]
#![feature(box_syntax)]
......
......@@ -127,6 +127,9 @@ fn visit_mac(&mut self, _mac: &'v Mac) {
fn visit_path(&mut self, path: &'v Path, _id: ast::NodeId) {
walk_path(self, path)
}
fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) {
walk_path_list_item(self, prefix, item)
}
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
walk_path_segment(self, path_span, path_segment)
}
......@@ -209,33 +212,21 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
ItemExternCrate(..) => {}
ItemUse(ref vp) => {
match vp.node {
ViewPathSimple(ident, ref path) => {
visitor.visit_ident(vp.span, ident);
ViewPathSimple(_ident, ref path) => {
visitor.visit_path(path, item.id);
}
ViewPathGlob(ref path) => {
visitor.visit_path(path, item.id);
}
ViewPathList(ref prefix, ref list) => {
for id in list {
match id.node {
PathListIdent { name, rename, .. } => {
visitor.visit_ident(id.span, name);
if let Some(ident) = rename {
visitor.visit_ident(id.span, ident);
}
}
PathListMod { rename, .. } => {
if let Some(ident) = rename {
visitor.visit_ident(id.span, ident);
}
}
if !list.is_empty() {
for item in list {
visitor.visit_path_list_item(prefix, item)
}
} else {
// FIXME: uncomment this and fix the resulting ICE
// visitor.visit_path(prefix, item.id);
}
// Note that the `prefix` here is not a complete
// path, so we don't use `visit_path`.
walk_path(visitor, prefix);
}
}
}
......@@ -417,6 +408,17 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
}
}
pub fn walk_path_list_item<'v, V: Visitor<'v>>(visitor: &mut V, prefix: &'v Path,
item: &'v PathListItem) {
for segment in &prefix.segments {
visitor.visit_path_segment(prefix.span, segment);
}
if let PathListIdent { name, .. } = item.node {
visitor.visit_ident(item.span, name);
}
}
pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
path_span: Span,
segment: &'v PathSegment) {
......
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Unstable entities should be caught in import lists
#![allow(unused_imports)]
use std::thread::{catch_panic, sleep}; //~ ERROR use of unstable library feature 'catch_panic'
//~^ ERROR use of unstable library feature 'thread_sleep'
use std::rt::{self}; //~ ERROR use of unstable library feature 'rt'
use std::rt::{};
fn main() {
}
......@@ -14,7 +14,8 @@
#![feature(foo)] //~ ERROR unused or unknown feature
extern crate lint_output_format; //~ ERROR use of unstable library feature
use lint_output_format::{foo, bar};
use lint_output_format::{foo, bar}; //~ ERROR use of unstable library feature
//~^ WARNING use of deprecated item,
fn main() {
let _x = foo(); //~ WARNING #[warn(deprecated)] on by default
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册