Auto merge of #33091 - sanxiyn:unused-trait-import-3, r=nrc
Warn unused trait imports, rebased Rebase of #30021. Fix #25730.
This commit is contained in:
commit
8e414e0e3f
@ -15,7 +15,6 @@
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cell_extras)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(core_float)]
|
||||
#![feature(core_private_bignum)]
|
||||
#![feature(core_private_diy_float)]
|
||||
#![feature(dec2flt)]
|
||||
|
@ -52,7 +52,6 @@ pub fn test_num<T>(ten: T, two: T) where
|
||||
mod tests {
|
||||
use core::option::Option;
|
||||
use core::option::Option::{Some, None};
|
||||
use core::num::Float;
|
||||
|
||||
#[test]
|
||||
fn from_str_issue7588() {
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
//! The exponential distribution.
|
||||
|
||||
#[cfg(not(test))] // only necessary for no_std
|
||||
use FloatMath;
|
||||
|
||||
use {Rng, Rand};
|
||||
|
@ -13,6 +13,7 @@
|
||||
use self::GammaRepr::*;
|
||||
use self::ChiSquaredRepr::*;
|
||||
|
||||
#[cfg(not(test))] // only necessary for no_std
|
||||
use FloatMath;
|
||||
|
||||
use {Rng, Open01};
|
||||
|
@ -17,7 +17,9 @@
|
||||
//! internally. The `IndependentSample` trait is for generating values
|
||||
//! that do not need to record state.
|
||||
|
||||
#[cfg(not(test))] // only necessary for no_std
|
||||
use core::num::Float;
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use {Rng, Rand};
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
//! The normal and derived distributions.
|
||||
|
||||
#[cfg(not(test))] // only necessary for no_std
|
||||
use FloatMath;
|
||||
|
||||
use {Rng, Rand, Open01};
|
||||
|
@ -28,13 +28,13 @@
|
||||
#![unstable(feature = "rand",
|
||||
reason = "use `rand` from crates.io",
|
||||
issue = "27703")]
|
||||
#![feature(core_float)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(step_by)]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(unused_attributes)]
|
||||
|
||||
#![cfg_attr(not(test), feature(core_float))] // only necessary for no_std
|
||||
#![cfg_attr(test, feature(test, rand))]
|
||||
|
||||
#![allow(deprecated)]
|
||||
|
@ -59,6 +59,7 @@ pub enum DepNode<D: Clone + Debug> {
|
||||
TypeckItemBody(D),
|
||||
Dropck,
|
||||
DropckImpl(D),
|
||||
UnusedTraitCheck,
|
||||
CheckConst(D),
|
||||
Privacy,
|
||||
IntrinsicCheck(D),
|
||||
@ -165,6 +166,7 @@ impl<D: Clone + Debug> DepNode<D> {
|
||||
CheckEntryFn => Some(CheckEntryFn),
|
||||
Variance => Some(Variance),
|
||||
Dropck => Some(Dropck),
|
||||
UnusedTraitCheck => Some(UnusedTraitCheck),
|
||||
Privacy => Some(Privacy),
|
||||
Reachability => Some(Reachability),
|
||||
DeadCheck => Some(DeadCheck),
|
||||
|
@ -1639,8 +1639,13 @@ pub type FreevarMap = NodeMap<Vec<Freevar>>;
|
||||
|
||||
pub type CaptureModeMap = NodeMap<CaptureClause>;
|
||||
|
||||
pub struct TraitCandidate {
|
||||
pub def_id: DefId,
|
||||
pub import_id: Option<NodeId>,
|
||||
}
|
||||
|
||||
// Trait method resolution
|
||||
pub type TraitMap = NodeMap<Vec<DefId>>;
|
||||
pub type TraitMap = NodeMap<Vec<TraitCandidate>>;
|
||||
|
||||
// Map from the NodeId of a glob import to a list of items which are actually
|
||||
// imported.
|
||||
|
@ -289,6 +289,8 @@ pub struct TyCtxt<'tcx> {
|
||||
// scratch every time.
|
||||
pub freevars: RefCell<FreevarMap>,
|
||||
|
||||
pub maybe_unused_trait_imports: NodeSet,
|
||||
|
||||
// Records the type of every item.
|
||||
pub tcache: RefCell<DepTrackingMap<maps::Tcache<'tcx>>>,
|
||||
|
||||
@ -338,6 +340,10 @@ pub struct TyCtxt<'tcx> {
|
||||
/// about.
|
||||
pub used_mut_nodes: RefCell<NodeSet>,
|
||||
|
||||
/// Set of trait imports actually used in the method resolution.
|
||||
/// This is used for warning unused imports.
|
||||
pub used_trait_imports: RefCell<NodeSet>,
|
||||
|
||||
/// The set of external nominal types whose implementations have been read.
|
||||
/// This is used for lazy resolution of methods.
|
||||
pub populated_external_types: RefCell<DefIdSet>,
|
||||
@ -543,6 +549,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
named_region_map: resolve_lifetime::NamedRegionMap,
|
||||
map: ast_map::Map<'tcx>,
|
||||
freevars: FreevarMap,
|
||||
maybe_unused_trait_imports: NodeSet,
|
||||
region_maps: RegionMaps,
|
||||
lang_items: middle::lang_items::LanguageItems,
|
||||
stability: stability::Index<'tcx>,
|
||||
@ -581,6 +588,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
fulfilled_predicates: RefCell::new(fulfilled_predicates),
|
||||
map: map,
|
||||
freevars: RefCell::new(freevars),
|
||||
maybe_unused_trait_imports: maybe_unused_trait_imports,
|
||||
tcache: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
||||
rcache: RefCell::new(FnvHashMap()),
|
||||
tc_cache: RefCell::new(FnvHashMap()),
|
||||
@ -595,6 +603,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
impl_items: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
||||
used_unsafe: RefCell::new(NodeSet()),
|
||||
used_mut_nodes: RefCell::new(NodeSet()),
|
||||
used_trait_imports: RefCell::new(NodeSet()),
|
||||
populated_external_types: RefCell::new(DefIdSet()),
|
||||
populated_external_primitive_impls: RefCell::new(DefIdSet()),
|
||||
extern_const_statics: RefCell::new(DefIdMap()),
|
||||
|
@ -531,7 +531,7 @@ mod tests {
|
||||
use self::rand::isaac::IsaacRng;
|
||||
use serialize::hex::FromHex;
|
||||
use std::u64;
|
||||
use super::{Digest, Sha256, FixedBuffer};
|
||||
use super::{Digest, Sha256};
|
||||
|
||||
// A normal addition - no overflow occurs
|
||||
#[test]
|
||||
@ -648,7 +648,7 @@ mod tests {
|
||||
mod bench {
|
||||
extern crate test;
|
||||
use self::test::Bencher;
|
||||
use super::{Sha256, FixedBuffer, Digest};
|
||||
use super::{Sha256, Digest};
|
||||
|
||||
#[bench]
|
||||
pub fn sha256_10(b: &mut Bencher) {
|
||||
|
@ -17,7 +17,7 @@ use self::EvalHint::*;
|
||||
|
||||
use rustc::hir::map as ast_map;
|
||||
use rustc::hir::map::blocks::FnLikeNode;
|
||||
use rustc::middle::cstore::{self, CrateStore, InlinedItem};
|
||||
use rustc::middle::cstore::{self, InlinedItem};
|
||||
use rustc::{infer, traits};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::DefId;
|
||||
|
@ -791,6 +791,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||
let resolve::CrateMap {
|
||||
def_map,
|
||||
freevars,
|
||||
maybe_unused_trait_imports,
|
||||
export_map,
|
||||
trait_map,
|
||||
glob_map,
|
||||
@ -840,6 +841,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||
named_region_map,
|
||||
hir_map,
|
||||
freevars,
|
||||
maybe_unused_trait_imports,
|
||||
region_map,
|
||||
lang_items,
|
||||
index,
|
||||
|
@ -70,7 +70,6 @@ use rustc_trans::back::link;
|
||||
use rustc::session::{self, config, Session, build_session, CompileResult};
|
||||
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
|
||||
use rustc::session::config::{get_unstable_features_setting, nightly_options};
|
||||
use rustc::middle::cstore::CrateStore;
|
||||
use rustc::lint::Lint;
|
||||
use rustc::lint;
|
||||
use rustc_metadata::loader;
|
||||
|
@ -24,7 +24,6 @@ use rustc::ty::subst;
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc::traits::ProjectionMode;
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::relate::TypeRelation;
|
||||
use rustc::infer::{self, InferOk, InferResult, TypeOrigin};
|
||||
use rustc_metadata::cstore::CStore;
|
||||
use rustc_metadata::creader::LocalCrateReader;
|
||||
@ -132,7 +131,7 @@ fn test_env<F>(source_string: &str,
|
||||
|
||||
// run just enough stuff to build a tcx:
|
||||
let lang_items = lang_items::collect_language_items(&sess, &ast_map);
|
||||
let resolve::CrateMap { def_map, freevars, .. } =
|
||||
let resolve::CrateMap { def_map, freevars, maybe_unused_trait_imports, .. } =
|
||||
resolve::resolve_crate(&sess, &ast_map, resolve::MakeGlobMap::No);
|
||||
let named_region_map = resolve_lifetime::krate(&sess, &ast_map, &def_map.borrow());
|
||||
let region_map = region::resolve_crate(&sess, &ast_map);
|
||||
@ -143,6 +142,7 @@ fn test_env<F>(source_string: &str,
|
||||
named_region_map.unwrap(),
|
||||
ast_map,
|
||||
freevars,
|
||||
maybe_unused_trait_imports,
|
||||
region_map,
|
||||
lang_items,
|
||||
index,
|
||||
|
@ -11,7 +11,6 @@
|
||||
//! The data that we will serialize and deserialize.
|
||||
|
||||
use rustc::dep_graph::DepNode;
|
||||
use rustc_serialize::{Decoder as RustcDecoder, Encoder as RustcEncoder};
|
||||
|
||||
use super::directory::DefPathIndex;
|
||||
|
||||
|
@ -18,7 +18,6 @@ use rustc::hir::map::DefPath;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty;
|
||||
use rustc::util::nodemap::DefIdMap;
|
||||
use rustc_serialize::{Decoder as RustcDecoder, Encoder as RustcEncoder};
|
||||
use std::fmt::{self, Debug};
|
||||
|
||||
/// Index into the DefIdDirectory
|
||||
|
@ -29,7 +29,6 @@
|
||||
//! a `pub fn new()`.
|
||||
|
||||
use rustc::hir::def::Def;
|
||||
use middle::cstore::CrateStore;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use middle::stability;
|
||||
use rustc::{cfg, infer};
|
||||
|
@ -26,7 +26,7 @@ use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::abi::Abi;
|
||||
use syntax::attr::{self, AttrMetaMethods};
|
||||
use syntax::attr;
|
||||
use syntax::codemap::{self, Span};
|
||||
|
||||
use rustc::hir;
|
||||
|
@ -536,7 +536,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
||||
let mut visible_parent_map = self.visible_parent_map.borrow_mut();
|
||||
if !visible_parent_map.is_empty() { return visible_parent_map; }
|
||||
|
||||
use rustc::middle::cstore::{CrateStore, ChildItem};
|
||||
use rustc::middle::cstore::ChildItem;
|
||||
use std::collections::vec_deque::VecDeque;
|
||||
use std::collections::hash_map::Entry;
|
||||
for cnum in 1 .. self.next_crate_num() {
|
||||
|
@ -43,7 +43,6 @@ use rustc::mir;
|
||||
use rustc::mir::visit::MutVisitor;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::io::prelude::*;
|
||||
use std::io;
|
||||
use std::rc::Rc;
|
||||
use std::str;
|
||||
|
@ -21,7 +21,7 @@ use def_key;
|
||||
use tyencode;
|
||||
use index::{self, IndexData};
|
||||
|
||||
use middle::cstore::{LOCAL_CRATE, CrateStore, InlinedItemRef, LinkMeta, tls};
|
||||
use middle::cstore::{LOCAL_CRATE, InlinedItemRef, LinkMeta, tls};
|
||||
use rustc::hir::def;
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
|
||||
use middle::dependency_format::Linkage;
|
||||
@ -46,7 +46,6 @@ use syntax::abi::Abi;
|
||||
use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum};
|
||||
use syntax::codemap::BytePos;
|
||||
use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::errors::Handler;
|
||||
use syntax;
|
||||
use rbml::writer::Encoder;
|
||||
|
@ -233,7 +233,6 @@ use std::cmp;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::io::prelude::*;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::ptr;
|
||||
|
@ -34,7 +34,6 @@ use rustc::hir::intravisit::{self, Visitor};
|
||||
|
||||
use rustc::dep_graph::DepNode;
|
||||
use rustc::lint;
|
||||
use rustc::middle::cstore::CrateStore;
|
||||
use rustc::hir::def::{self, Def};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::privacy::{AccessLevel, AccessLevels};
|
||||
|
@ -21,7 +21,7 @@ use ParentLink::{ModuleParentLink, BlockParentLink};
|
||||
use Resolver;
|
||||
use {resolve_error, resolve_struct_error, ResolutionError};
|
||||
|
||||
use rustc::middle::cstore::{CrateStore, ChildItem, DlDef};
|
||||
use rustc::middle::cstore::{ChildItem, DlDef};
|
||||
use rustc::lint;
|
||||
use rustc::hir::def::*;
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
|
||||
|
@ -16,6 +16,8 @@
|
||||
// resolve data structures and because it finalises the privacy information for
|
||||
// `use` directives.
|
||||
//
|
||||
// Unused trait imports can't be checked until the method resolution. We save
|
||||
// candidates here, and do the acutal check in librustc_typeck/check_unused.rs.
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
@ -55,10 +57,18 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
|
||||
fn check_import(&mut self, id: ast::NodeId, span: Span) {
|
||||
if !self.used_imports.contains(&(id, TypeNS)) &&
|
||||
!self.used_imports.contains(&(id, ValueNS)) {
|
||||
if self.maybe_unused_trait_imports.contains(&id) {
|
||||
// Check later.
|
||||
return;
|
||||
}
|
||||
self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
|
||||
id,
|
||||
span,
|
||||
"unused import".to_string());
|
||||
} else {
|
||||
// This trait import is definitely used, in a way other than
|
||||
// method resolution.
|
||||
self.maybe_unused_trait_imports.remove(&id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,18 +47,16 @@ use rustc::dep_graph::DepNode;
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::session::Session;
|
||||
use rustc::lint;
|
||||
use rustc::middle::cstore::CrateStore;
|
||||
use rustc::hir::def::*;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::pat_util::pat_bindings;
|
||||
use rustc::ty;
|
||||
use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace};
|
||||
use rustc::hir::{Freevar, FreevarMap, TraitMap, GlobMap};
|
||||
use rustc::util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};
|
||||
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
|
||||
use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet};
|
||||
|
||||
use syntax::ast::{self, FloatTy};
|
||||
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::{self, Span, Pos};
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use syntax::parse::token::{self, keywords};
|
||||
@ -1056,6 +1054,7 @@ pub struct Resolver<'a, 'tcx: 'a> {
|
||||
|
||||
used_imports: HashSet<(NodeId, Namespace)>,
|
||||
used_crates: HashSet<CrateNum>,
|
||||
maybe_unused_trait_imports: NodeSet,
|
||||
|
||||
privacy_errors: Vec<PrivacyError<'a>>,
|
||||
|
||||
@ -1151,13 +1150,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
export_map: NodeMap(),
|
||||
trait_map: NodeMap(),
|
||||
module_map: module_map,
|
||||
used_imports: HashSet::new(),
|
||||
used_crates: HashSet::new(),
|
||||
|
||||
emit_errors: true,
|
||||
make_glob_map: make_glob_map == MakeGlobMap::Yes,
|
||||
glob_map: NodeMap(),
|
||||
|
||||
used_imports: HashSet::new(),
|
||||
used_crates: HashSet::new(),
|
||||
maybe_unused_trait_imports: NodeSet(),
|
||||
|
||||
privacy_errors: Vec::new(),
|
||||
|
||||
arenas: arenas,
|
||||
@ -1191,7 +1192,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn record_use(&mut self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>) {
|
||||
fn record_use(&mut self, name: Name, binding: &'a NameBinding<'a>) {
|
||||
// track extern crates for unused_extern_crate lint
|
||||
if let Some(DefId { krate, .. }) = binding.module().and_then(ModuleS::def_id) {
|
||||
self.used_crates.insert(krate);
|
||||
@ -1203,7 +1204,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
_ => return,
|
||||
};
|
||||
|
||||
self.used_imports.insert((directive.id, ns));
|
||||
if let Some(error) = privacy_error.as_ref() {
|
||||
self.privacy_errors.push((**error).clone());
|
||||
}
|
||||
@ -1506,7 +1506,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
false => module.resolve_name(name, namespace, false),
|
||||
}.and_then(|binding| {
|
||||
if record_used {
|
||||
self.record_use(name, namespace, binding);
|
||||
if let NameBindingKind::Import { directive, .. } = binding.kind {
|
||||
self.used_imports.insert((directive.id, namespace));
|
||||
}
|
||||
self.record_use(name, binding);
|
||||
}
|
||||
Success(binding)
|
||||
})
|
||||
@ -3110,21 +3113,27 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_traits_containing_item(&mut self, name: Name) -> Vec<DefId> {
|
||||
fn get_traits_containing_item(&mut self, name: Name) -> Vec<TraitCandidate> {
|
||||
debug!("(getting traits containing item) looking for '{}'", name);
|
||||
|
||||
fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name) {
|
||||
fn add_trait_info(found_traits: &mut Vec<TraitCandidate>,
|
||||
trait_def_id: DefId,
|
||||
import_id: Option<NodeId>,
|
||||
name: Name) {
|
||||
debug!("(adding trait info) found trait {:?} for method '{}'",
|
||||
trait_def_id,
|
||||
name);
|
||||
found_traits.push(trait_def_id);
|
||||
found_traits.push(TraitCandidate {
|
||||
def_id: trait_def_id,
|
||||
import_id: import_id,
|
||||
});
|
||||
}
|
||||
|
||||
let mut found_traits = Vec::new();
|
||||
// Look for the current trait.
|
||||
if let Some((trait_def_id, _)) = self.current_trait_ref {
|
||||
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
|
||||
add_trait_info(&mut found_traits, trait_def_id, name);
|
||||
add_trait_info(&mut found_traits, trait_def_id, None, name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3147,8 +3156,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
|
||||
let trait_def_id = binding.def().unwrap().def_id();
|
||||
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
|
||||
add_trait_info(&mut found_traits, trait_def_id, name);
|
||||
self.record_use(trait_name, TypeNS, binding);
|
||||
let mut import_id = None;
|
||||
if let NameBindingKind::Import { directive, .. } = binding.kind {
|
||||
let id = directive.id;
|
||||
self.maybe_unused_trait_imports.insert(id);
|
||||
import_id = Some(id);
|
||||
}
|
||||
add_trait_info(&mut found_traits, trait_def_id, import_id, name);
|
||||
self.record_use(trait_name, binding);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -3522,6 +3537,7 @@ fn err_path_resolution() -> PathResolution {
|
||||
pub struct CrateMap {
|
||||
pub def_map: RefCell<DefMap>,
|
||||
pub freevars: FreevarMap,
|
||||
pub maybe_unused_trait_imports: NodeSet,
|
||||
pub export_map: ExportMap,
|
||||
pub trait_map: TraitMap,
|
||||
pub glob_map: Option<GlobMap>,
|
||||
@ -3559,6 +3575,7 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
|
||||
CrateMap {
|
||||
def_map: resolver.def_map,
|
||||
freevars: resolver.freevars,
|
||||
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
|
||||
export_map: resolver.export_map,
|
||||
trait_map: resolver.trait_map,
|
||||
glob_map: if resolver.make_glob_map {
|
||||
|
@ -25,7 +25,6 @@ use rustc::lint;
|
||||
use rustc::hir::def::*;
|
||||
|
||||
use syntax::ast::{NodeId, Name};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
use syntax::util::lev_distance::find_best_match_for_name;
|
||||
|
||||
|
@ -13,8 +13,6 @@
|
||||
//! The `Dump` trait can be used together with `DumpVisitor` in order to
|
||||
//! retrieve the data from a crate.
|
||||
|
||||
use std::hash::Hasher;
|
||||
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty;
|
||||
use syntax::ast::{CrateNum, NodeId};
|
||||
|
@ -21,8 +21,6 @@ use std::process::{Command, Output, Stdio};
|
||||
use std::ptr;
|
||||
use std::str;
|
||||
|
||||
use middle::cstore::CrateStore;
|
||||
|
||||
use libc;
|
||||
use llvm::archive_ro::{ArchiveRO, Child};
|
||||
use llvm::{self, ArchiveKind};
|
||||
|
@ -19,7 +19,7 @@ use session::config::{OutputFilenames, Input, OutputType};
|
||||
use session::filesearch;
|
||||
use session::search_paths::PathKind;
|
||||
use session::Session;
|
||||
use middle::cstore::{self, CrateStore, LinkMeta};
|
||||
use middle::cstore::{self, LinkMeta};
|
||||
use middle::cstore::{LinkagePreference, NativeLibraryKind};
|
||||
use middle::dependency_format::Linkage;
|
||||
use CrateTranslation;
|
||||
|
@ -16,7 +16,6 @@ use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use back::archive;
|
||||
use middle::cstore::CrateStore;
|
||||
use middle::dependency_format::Linkage;
|
||||
use session::Session;
|
||||
use session::config::CrateTypeDylib;
|
||||
|
@ -35,7 +35,6 @@ use lint;
|
||||
use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
|
||||
use llvm;
|
||||
use rustc::cfg;
|
||||
use middle::cstore::CrateStore;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer;
|
||||
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
|
||||
|
@ -39,7 +39,7 @@ use type_::Type;
|
||||
use value::Value;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::traits::{self, SelectionContext, ProjectionMode};
|
||||
use rustc::ty::fold::{TypeFolder, TypeFoldable};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::hir;
|
||||
use util::nodemap::NodeMap;
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use llvm::{AvailableExternallyLinkage, InternalLinkage, SetLinkage};
|
||||
use middle::cstore::{CrateStore, FoundAst, InlinedItem};
|
||||
use middle::cstore::{FoundAst, InlinedItem};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::subst::Substs;
|
||||
use base::{push_ctxt, trans_item, trans_fn};
|
||||
|
@ -71,7 +71,7 @@ use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
|
||||
use rustc::ty::{self, LvaluePreference, TypeAndMut, Ty, TyCtxt};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::error::TypeError;
|
||||
use rustc::ty::relate::{RelateResult, TypeRelation};
|
||||
use rustc::ty::relate::RelateResult;
|
||||
use util::common::indent;
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
@ -11,18 +11,15 @@
|
||||
//! Type-checking for the rust-intrinsic and platform-intrinsic
|
||||
//! intrinsics that the compiler exposes.
|
||||
|
||||
use astconv::AstConv;
|
||||
use intrinsics;
|
||||
use rustc::ty::subst::{self, Substs};
|
||||
use rustc::ty::FnSig;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::fold::TypeFolder;
|
||||
use {CrateCtxt, require_same_types};
|
||||
|
||||
use std::collections::{HashMap};
|
||||
use syntax::abi::Abi;
|
||||
use syntax::ast;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token;
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
//! Method lookup: the secret sauce of Rust. See `README.md`.
|
||||
|
||||
use astconv::AstConv;
|
||||
use check::FnCtxt;
|
||||
use hir::def::Def;
|
||||
use hir::def_id::DefId;
|
||||
@ -129,6 +128,11 @@ pub fn lookup<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
let mode = probe::Mode::MethodCall;
|
||||
let self_ty = fcx.infcx().resolve_type_vars_if_possible(&self_ty);
|
||||
let pick = probe::probe(fcx, span, mode, method_name, self_ty, call_expr.id)?;
|
||||
|
||||
if let Some(import_id) = pick.import_id {
|
||||
fcx.tcx().used_trait_imports.borrow_mut().insert(import_id);
|
||||
}
|
||||
|
||||
Ok(confirm::confirm(fcx, span, self_expr, call_expr, self_ty, pick, supplied_method_types))
|
||||
}
|
||||
|
||||
@ -340,8 +344,12 @@ pub fn resolve_ufcs<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
{
|
||||
let mode = probe::Mode::Path;
|
||||
let pick = probe::probe(fcx, span, mode, method_name, self_ty, expr_id)?;
|
||||
let def = pick.item.def();
|
||||
|
||||
if let Some(import_id) = pick.import_id {
|
||||
fcx.tcx().used_trait_imports.borrow_mut().insert(import_id);
|
||||
}
|
||||
|
||||
let def = pick.item.def();
|
||||
if let probe::InherentImplPick = pick.kind {
|
||||
if !pick.item.vis().is_accessible_from(fcx.body_id, &fcx.tcx().map) {
|
||||
let msg = format!("{} `{}` is private", def.kind_name(), &method_name.as_str());
|
||||
|
@ -42,6 +42,7 @@ struct ProbeContext<'a, 'tcx:'a> {
|
||||
inherent_candidates: Vec<Candidate<'tcx>>,
|
||||
extension_candidates: Vec<Candidate<'tcx>>,
|
||||
impl_dups: HashSet<DefId>,
|
||||
import_id: Option<ast::NodeId>,
|
||||
|
||||
/// Collects near misses when the candidate functions are missing a `self` keyword and is only
|
||||
/// used for error reporting
|
||||
@ -67,6 +68,7 @@ struct Candidate<'tcx> {
|
||||
xform_self_ty: Ty<'tcx>,
|
||||
item: ty::ImplOrTraitItem<'tcx>,
|
||||
kind: CandidateKind<'tcx>,
|
||||
import_id: Option<ast::NodeId>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -84,6 +86,7 @@ enum CandidateKind<'tcx> {
|
||||
pub struct Pick<'tcx> {
|
||||
pub item: ty::ImplOrTraitItem<'tcx>,
|
||||
pub kind: PickKind<'tcx>,
|
||||
pub import_id: Option<ast::NodeId>,
|
||||
|
||||
// Indicates that the source expression should be autoderef'd N times
|
||||
//
|
||||
@ -247,6 +250,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
inherent_candidates: Vec::new(),
|
||||
extension_candidates: Vec::new(),
|
||||
impl_dups: HashSet::new(),
|
||||
import_id: None,
|
||||
steps: Rc::new(steps),
|
||||
opt_simplified_steps: opt_simplified_steps,
|
||||
static_candidates: Vec::new(),
|
||||
@ -435,7 +439,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
self.inherent_candidates.push(Candidate {
|
||||
xform_self_ty: xform_self_ty,
|
||||
item: item,
|
||||
kind: InherentImplCandidate(impl_substs, obligations)
|
||||
kind: InherentImplCandidate(impl_substs, obligations),
|
||||
import_id: self.import_id,
|
||||
});
|
||||
}
|
||||
|
||||
@ -463,7 +468,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
this.inherent_candidates.push(Candidate {
|
||||
xform_self_ty: xform_self_ty,
|
||||
item: item,
|
||||
kind: ObjectCandidate
|
||||
kind: ObjectCandidate,
|
||||
import_id: this.import_id,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -534,7 +540,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
this.inherent_candidates.push(Candidate {
|
||||
xform_self_ty: xform_self_ty,
|
||||
item: item,
|
||||
kind: WhereClauseCandidate(poly_trait_ref)
|
||||
kind: WhereClauseCandidate(poly_trait_ref),
|
||||
import_id: this.import_id,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -578,9 +585,13 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
let mut duplicates = HashSet::new();
|
||||
let opt_applicable_traits = self.fcx.ccx.trait_map.get(&expr_id);
|
||||
if let Some(applicable_traits) = opt_applicable_traits {
|
||||
for &trait_did in applicable_traits {
|
||||
for trait_candidate in applicable_traits {
|
||||
let trait_did = trait_candidate.def_id;
|
||||
if duplicates.insert(trait_did) {
|
||||
self.assemble_extension_candidates_for_trait(trait_did)?;
|
||||
self.import_id = trait_candidate.import_id;
|
||||
let result = self.assemble_extension_candidates_for_trait(trait_did);
|
||||
self.import_id = None;
|
||||
result?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -680,7 +691,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
self.extension_candidates.push(Candidate {
|
||||
xform_self_ty: xform_self_ty,
|
||||
item: item.clone(),
|
||||
kind: ExtensionImplCandidate(impl_def_id, impl_substs, obligations)
|
||||
kind: ExtensionImplCandidate(impl_def_id, impl_substs, obligations),
|
||||
import_id: self.import_id,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -755,7 +767,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
self.inherent_candidates.push(Candidate {
|
||||
xform_self_ty: xform_self_ty,
|
||||
item: item.clone(),
|
||||
kind: TraitCandidate
|
||||
kind: TraitCandidate,
|
||||
import_id: self.import_id,
|
||||
});
|
||||
}
|
||||
|
||||
@ -812,7 +825,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
self.extension_candidates.push(Candidate {
|
||||
xform_self_ty: xform_self_ty,
|
||||
item: item.clone(),
|
||||
kind: TraitCandidate
|
||||
kind: TraitCandidate,
|
||||
import_id: self.import_id,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -843,7 +857,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
self.extension_candidates.push(Candidate {
|
||||
xform_self_ty: xform_self_ty,
|
||||
item: item.clone(),
|
||||
kind: WhereClauseCandidate(poly_bound)
|
||||
kind: WhereClauseCandidate(poly_bound),
|
||||
import_id: self.import_id,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1141,6 +1156,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
Some(Pick {
|
||||
item: probes[0].item.clone(),
|
||||
kind: TraitPick,
|
||||
import_id: probes[0].import_id,
|
||||
autoderefs: 0,
|
||||
autoref: None,
|
||||
unsize: None
|
||||
@ -1346,6 +1362,7 @@ impl<'tcx> Candidate<'tcx> {
|
||||
WhereClausePick(trait_ref.clone())
|
||||
}
|
||||
},
|
||||
import_id: self.import_id,
|
||||
autoderefs: 0,
|
||||
autoref: None,
|
||||
unsize: None
|
||||
|
@ -13,11 +13,10 @@
|
||||
|
||||
use CrateCtxt;
|
||||
|
||||
use astconv::AstConv;
|
||||
use check::{self, FnCtxt, UnresolvedTypeAction, autoderef};
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable};
|
||||
use middle::cstore::{self, CrateStore};
|
||||
use middle::cstore;
|
||||
use hir::def::Def;
|
||||
use hir::def_id::DefId;
|
||||
use middle::lang_items::FnOnceTraitLangItem;
|
||||
|
@ -99,8 +99,7 @@ use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, Visibility};
|
||||
use rustc::ty::{MethodCall, MethodCallee};
|
||||
use rustc::ty::adjustment;
|
||||
use rustc::ty::error::TypeError;
|
||||
use rustc::ty::fold::{TypeFolder, TypeFoldable};
|
||||
use rustc::ty::relate::TypeRelation;
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::util::{Representability, IntTypeExt};
|
||||
use require_c_abi_if_variadic;
|
||||
use rscope::{ElisionFailureInfo, RegionScope};
|
||||
|
@ -82,7 +82,6 @@
|
||||
//! relation, except that a borrowed pointer never owns its
|
||||
//! contents.
|
||||
|
||||
use astconv::AstConv;
|
||||
use check::dropck;
|
||||
use check::FnCtxt;
|
||||
use middle::free_region::FreeRegionMap;
|
||||
|
@ -8,7 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use astconv::AstConv;
|
||||
use check::{FnCtxt, Inherited, blank_fn_ctxt, regionck};
|
||||
use constrained_type_params::{identify_constrained_type_params, Parameter};
|
||||
use CrateCtxt;
|
||||
@ -17,7 +16,6 @@ use middle::region::{CodeExtent};
|
||||
use rustc::ty::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::fold::{TypeFolder};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashSet;
|
||||
|
@ -13,7 +13,6 @@
|
||||
// substitutions.
|
||||
use self::ResolveReason::*;
|
||||
|
||||
use astconv::AstConv;
|
||||
use check::FnCtxt;
|
||||
use hir::def_id::DefId;
|
||||
use hir::pat_util;
|
||||
|
64
src/librustc_typeck/check_unused.rs
Normal file
64
src/librustc_typeck/check_unused.rs
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
use lint;
|
||||
use rustc::dep_graph::DepNode;
|
||||
use rustc::ty::TyCtxt;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::Visitor;
|
||||
|
||||
struct UnusedTraitImportVisitor<'a, 'tcx: 'a> {
|
||||
tcx: &'a TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> UnusedTraitImportVisitor<'a, 'tcx> {
|
||||
fn check_import(&self, id: ast::NodeId, span: Span) {
|
||||
if !self.tcx.maybe_unused_trait_imports.contains(&id) {
|
||||
return;
|
||||
}
|
||||
if self.tcx.used_trait_imports.borrow().contains(&id) {
|
||||
return;
|
||||
}
|
||||
self.tcx.sess.add_lint(lint::builtin::UNUSED_IMPORTS,
|
||||
id,
|
||||
span,
|
||||
"unused import".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> Visitor<'v> for UnusedTraitImportVisitor<'a, 'tcx> {
|
||||
fn visit_item(&mut self, item: &hir::Item) {
|
||||
if item.vis == hir::Public || item.span == DUMMY_SP {
|
||||
return;
|
||||
}
|
||||
if let hir::ItemUse(ref path) = item.node {
|
||||
match path.node {
|
||||
hir::ViewPathSimple(..) | hir::ViewPathGlob(..) => {
|
||||
self.check_import(item.id, path.span);
|
||||
}
|
||||
hir::ViewPathList(_, ref path_list) => {
|
||||
for path_item in path_list {
|
||||
self.check_import(path_item.node.id(), path_item.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_crate(tcx: &TyCtxt) {
|
||||
let _task = tcx.dep_graph.in_task(DepNode::UnusedTraitCheck);
|
||||
let mut visitor = UnusedTraitImportVisitor { tcx: tcx };
|
||||
tcx.map.krate().visit_all_items(&mut visitor);
|
||||
}
|
@ -12,7 +12,6 @@
|
||||
//! same type. Likewise, no two inherent impls for a given type
|
||||
//! constructor provide a method with the same name.
|
||||
|
||||
use middle::cstore::CrateStore;
|
||||
use hir::def_id::DefId;
|
||||
use rustc::traits::{self, ProjectionMode};
|
||||
use rustc::infer;
|
||||
|
@ -73,7 +73,6 @@ use rustc::ty::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPer
|
||||
use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
|
||||
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
|
||||
use rustc::ty::{VariantKind};
|
||||
use rustc::ty::fold::{TypeFolder};
|
||||
use rustc::ty::util::IntTypeExt;
|
||||
use rscope::*;
|
||||
use rustc::dep_graph::DepNode;
|
||||
|
@ -122,6 +122,7 @@ use std::cell::RefCell;
|
||||
pub mod diagnostics;
|
||||
|
||||
pub mod check;
|
||||
pub mod check_unused;
|
||||
mod rscope;
|
||||
mod astconv;
|
||||
pub mod collect;
|
||||
@ -363,6 +364,7 @@ pub fn check_crate(tcx: &TyCtxt, trait_map: hir::TraitMap) -> CompileResult {
|
||||
|
||||
time(time_passes, "drop-impl checking", || check::check_drop_impls(&ccx))?;
|
||||
|
||||
check_unused::check_crate(tcx);
|
||||
check_for_entry_fn(&ccx);
|
||||
|
||||
let err_count = tcx.sess.err_count();
|
||||
|
@ -14,10 +14,9 @@ use std::collections::HashSet;
|
||||
use std::iter::once;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use rustc::hir;
|
||||
|
||||
use rustc::middle::cstore::{self, CrateStore};
|
||||
use rustc::middle::cstore;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::print as pprust;
|
||||
|
@ -35,7 +35,7 @@ use syntax::parse::token::{self, InternedString, keywords};
|
||||
use syntax::ptr::P;
|
||||
|
||||
use rustc_trans::back::link;
|
||||
use rustc::middle::cstore::{self, CrateStore};
|
||||
use rustc::middle::cstore;
|
||||
use rustc::middle::privacy::AccessLevels;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
|
||||
|
@ -9,7 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
use std::fmt;
|
||||
use std::io::prelude::*;
|
||||
use std::io;
|
||||
|
||||
use externalfiles::ExternalHtml;
|
||||
|
@ -11,7 +11,6 @@
|
||||
#![cfg(test)]
|
||||
|
||||
extern crate test;
|
||||
use prelude::v1::*;
|
||||
|
||||
use self::test::Bencher;
|
||||
|
||||
|
@ -350,7 +350,6 @@ mod test {
|
||||
use prelude::v1::*;
|
||||
use super::{Error, ErrorKind};
|
||||
use error;
|
||||
use error::Error as error_Error;
|
||||
use fmt;
|
||||
use sys::os::error_string;
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
use prelude::v1::*;
|
||||
use io::prelude::*;
|
||||
use os::windows::prelude::*;
|
||||
|
||||
use ffi::OsString;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use self::Destination::*;
|
||||
|
||||
use codemap::{self, COMMAND_LINE_SP, DUMMY_SP, Pos, Span, MultiSpan};
|
||||
use codemap::{self, COMMAND_LINE_SP, DUMMY_SP, Span, MultiSpan};
|
||||
use diagnostics;
|
||||
|
||||
use errors::check_old_skool;
|
||||
|
@ -12,7 +12,7 @@ use deriving::generic::*;
|
||||
use deriving::generic::ty::*;
|
||||
|
||||
use syntax::ast::{Expr, ItemKind, Generics, MetaItem, VariantData};
|
||||
use syntax::attr::{self, AttrMetaMethods};
|
||||
use syntax::attr;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ext::base::{ExtCtxt, Annotatable};
|
||||
use syntax::ext::build::AstBuilder;
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
fn main() { }
|
||||
|
||||
|
@ -24,6 +24,8 @@ use test::A; //~ ERROR unused import
|
||||
// Be sure that if we just bring some methods into scope that they're also
|
||||
// counted as being used.
|
||||
use test::B;
|
||||
// But only when actually used: do not get confused by the method with the same name.
|
||||
use test::B2; //~ ERROR unused import
|
||||
|
||||
// Make sure this import is warned about when at least one of its imported names
|
||||
// is unused
|
||||
@ -37,6 +39,7 @@ mod test2 {
|
||||
mod test {
|
||||
pub trait A { fn a(&self) {} }
|
||||
pub trait B { fn b(&self) {} }
|
||||
pub trait B2 { fn b(&self) {} }
|
||||
pub struct C;
|
||||
impl A for C {}
|
||||
impl B for C {}
|
||||
|
@ -25,7 +25,7 @@ const TEST_REPOS: &'static [Test] = &[
|
||||
Test {
|
||||
name: "cargo",
|
||||
repo: "https://github.com/rust-lang/cargo",
|
||||
sha: "fae9c539388f1b7c70c31fd0a21b5dd9cd071177",
|
||||
sha: "26288f799427f9cc6e8bdddd782a17a8156ebc64",
|
||||
lock: None,
|
||||
},
|
||||
Test {
|
||||
|
@ -19,10 +19,8 @@ extern crate rustdoc;
|
||||
extern crate rustc_back;
|
||||
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::process;
|
||||
use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT, Ordering};
|
||||
use subcommand::Subcommand;
|
||||
use term::Term;
|
||||
|
||||
mod term;
|
||||
|
Loading…
x
Reference in New Issue
Block a user