diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index aa7ab4b4e3f..dc01a9b5c78 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -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)] diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs index 11c1bd667fb..d5a6e0f87d6 100644 --- a/src/libcoretest/num/mod.rs +++ b/src/libcoretest/num/mod.rs @@ -52,7 +52,6 @@ pub fn test_num(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() { diff --git a/src/librand/distributions/exponential.rs b/src/librand/distributions/exponential.rs index f02b945178f..12dbbfdb0ed 100644 --- a/src/librand/distributions/exponential.rs +++ b/src/librand/distributions/exponential.rs @@ -10,6 +10,7 @@ //! The exponential distribution. +#[cfg(not(test))] // only necessary for no_std use FloatMath; use {Rng, Rand}; diff --git a/src/librand/distributions/gamma.rs b/src/librand/distributions/gamma.rs index 8cd7ac06f99..cf488236560 100644 --- a/src/librand/distributions/gamma.rs +++ b/src/librand/distributions/gamma.rs @@ -13,6 +13,7 @@ use self::GammaRepr::*; use self::ChiSquaredRepr::*; +#[cfg(not(test))] // only necessary for no_std use FloatMath; use {Rng, Open01}; diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs index a54c8df2352..2557d39c550 100644 --- a/src/librand/distributions/mod.rs +++ b/src/librand/distributions/mod.rs @@ -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}; diff --git a/src/librand/distributions/normal.rs b/src/librand/distributions/normal.rs index b2ccc5eb609..86840c568e0 100644 --- a/src/librand/distributions/normal.rs +++ b/src/librand/distributions/normal.rs @@ -10,6 +10,7 @@ //! The normal and derived distributions. +#[cfg(not(test))] // only necessary for no_std use FloatMath; use {Rng, Rand, Open01}; diff --git a/src/librand/lib.rs b/src/librand/lib.rs index e651f5bc182..d8517fb4c57 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -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)] diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 8378495599c..3e43c8e2c93 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -59,6 +59,7 @@ pub enum DepNode { TypeckItemBody(D), Dropck, DropckImpl(D), + UnusedTraitCheck, CheckConst(D), Privacy, IntrinsicCheck(D), @@ -165,6 +166,7 @@ impl DepNode { CheckEntryFn => Some(CheckEntryFn), Variance => Some(Variance), Dropck => Some(Dropck), + UnusedTraitCheck => Some(UnusedTraitCheck), Privacy => Some(Privacy), Reachability => Some(Reachability), DeadCheck => Some(DeadCheck), diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 7eaace91ae9..68e3e742d03 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1639,8 +1639,13 @@ pub type FreevarMap = NodeMap>; pub type CaptureModeMap = NodeMap; +pub struct TraitCandidate { + pub def_id: DefId, + pub import_id: Option, +} + // Trait method resolution -pub type TraitMap = NodeMap>; +pub type TraitMap = NodeMap>; // Map from the NodeId of a glob import to a list of items which are actually // imported. diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 5bde6df5123..c7ae038eb7a 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -289,6 +289,8 @@ pub struct TyCtxt<'tcx> { // scratch every time. pub freevars: RefCell, + pub maybe_unused_trait_imports: NodeSet, + // Records the type of every item. pub tcache: RefCell>>, @@ -338,6 +340,10 @@ pub struct TyCtxt<'tcx> { /// about. pub used_mut_nodes: RefCell, + /// Set of trait imports actually used in the method resolution. + /// This is used for warning unused imports. + pub used_trait_imports: RefCell, + /// The set of external nominal types whose implementations have been read. /// This is used for lazy resolution of methods. pub populated_external_types: RefCell, @@ -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()), diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs index 26f512e0613..404298d8839 100644 --- a/src/librustc_back/sha2.rs +++ b/src/librustc_back/sha2.rs @@ -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) { diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 06be29b9049..9d2922ae640 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -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; diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 1b570933bee..e791a351252 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -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, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 3b25104437a..299a20c1a0d 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -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; diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 37f7b31b69c..d546db086b5 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -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(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(source_string: &str, named_region_map.unwrap(), ast_map, freevars, + maybe_unused_trait_imports, region_map, lang_items, index, diff --git a/src/librustc_incremental/persist/data.rs b/src/librustc_incremental/persist/data.rs index 60d644ba768..37d5f8937f1 100644 --- a/src/librustc_incremental/persist/data.rs +++ b/src/librustc_incremental/persist/data.rs @@ -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; diff --git a/src/librustc_incremental/persist/directory.rs b/src/librustc_incremental/persist/directory.rs index 7f4c7d919c0..796812556d2 100644 --- a/src/librustc_incremental/persist/directory.rs +++ b/src/librustc_incremental/persist/directory.rs @@ -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 diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 4bdd926869a..6a51b1a43ad 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -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}; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 891731cb296..b81a4a0efe7 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -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; diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index 8e7be0e3a0f..6a79d5df80a 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -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() { diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index c911b20c2ab..dd5a643edc1 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -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; diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 40a7f91154f..7558e0774b3 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -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; diff --git a/src/librustc_metadata/loader.rs b/src/librustc_metadata/loader.rs index 2316a67d9d3..4ecb7a28ef7 100644 --- a/src/librustc_metadata/loader.rs +++ b/src/librustc_metadata/loader.rs @@ -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; diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index d55d0d53b8c..4a4b7caf478 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -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}; diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 4dc19434c80..f5e72195bc3 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -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}; diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 9135b656736..e213a51fb38 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -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); } } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index b590cc91c59..ff412be323a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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, + maybe_unused_trait_imports: NodeSet, privacy_errors: Vec>, @@ -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 { + fn get_traits_containing_item(&mut self, name: Name) -> Vec { debug!("(getting traits containing item) looking for '{}'", name); - fn add_trait_info(found_traits: &mut Vec, trait_def_id: DefId, name: Name) { + fn add_trait_info(found_traits: &mut Vec, + trait_def_id: DefId, + import_id: Option, + 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, pub freevars: FreevarMap, + pub maybe_unused_trait_imports: NodeSet, pub export_map: ExportMap, pub trait_map: TraitMap, pub glob_map: Option, @@ -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 { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index f0639a85176..e37dd4cbc6e 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -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; diff --git a/src/librustc_save_analysis/data.rs b/src/librustc_save_analysis/data.rs index b79c459920a..e654cef0c30 100644 --- a/src/librustc_save_analysis/data.rs +++ b/src/librustc_save_analysis/data.rs @@ -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}; diff --git a/src/librustc_trans/back/archive.rs b/src/librustc_trans/back/archive.rs index 514fc52d008..aea61da18a0 100644 --- a/src/librustc_trans/back/archive.rs +++ b/src/librustc_trans/back/archive.rs @@ -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}; diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 4e77b2bc069..3e69bb204b9 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -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; diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index c02a482f812..8055e97034e 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -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; diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index b100282781e..dd453bf9969 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -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}; diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 5ce7caf5deb..70348cf35e5 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -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; diff --git a/src/librustc_trans/inline.rs b/src/librustc_trans/inline.rs index 1eff09d67f9..af175fbf882 100644 --- a/src/librustc_trans/inline.rs +++ b/src/librustc_trans/inline.rs @@ -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}; diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 6c8d437f429..b30277d745e 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -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; diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index b71ee8722ab..29a9ae9e516 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -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; diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 31d95af4fbb..26d1f50f8c5 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -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()); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 8a71debdf20..0e064fbc45b 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -42,6 +42,7 @@ struct ProbeContext<'a, 'tcx:'a> { inherent_candidates: Vec>, extension_candidates: Vec>, impl_dups: HashSet, + import_id: Option, /// 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, } #[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, // 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 diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index fab3bb60e0b..6b90dcd54bf 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -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; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 6599199c239..10789228b97 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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}; diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 5efd57c4d1f..bda4c422880 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -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; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 25a37b6810e..ffdae233970 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -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; diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index ad78740921c..4341ae5dac1 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -13,7 +13,6 @@ // substitutions. use self::ResolveReason::*; -use astconv::AstConv; use check::FnCtxt; use hir::def_id::DefId; use hir::pat_util; diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs new file mode 100644 index 00000000000..3c594ebdf0b --- /dev/null +++ b/src/librustc_typeck/check_unused.rs @@ -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 or the MIT license +// , 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); +} diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index a05167dbe43..30d181abb9e 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -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; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4dd093e2e4b..19807ab840b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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; diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index c51304120a8..ed393b54f0e 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -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(); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 36eb1a1301c..742afdc5e98 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -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; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 398781e1405..f5b8db1143e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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}; diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 8b2e8497498..a168fe98a94 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -9,7 +9,6 @@ // except according to those terms. use std::fmt; -use std::io::prelude::*; use std::io; use externalfiles::ExternalHtml; diff --git a/src/libstd/collections/hash/bench.rs b/src/libstd/collections/hash/bench.rs index 9fae9af2d54..a1275d23d57 100644 --- a/src/libstd/collections/hash/bench.rs +++ b/src/libstd/collections/hash/bench.rs @@ -11,7 +11,6 @@ #![cfg(test)] extern crate test; -use prelude::v1::*; use self::test::Bencher; diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index 9a605fc7bbf..e142c78569b 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -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; diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 529e42248f6..3cd45afaf01 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -9,7 +9,6 @@ // except according to those terms. use prelude::v1::*; -use io::prelude::*; use os::windows::prelude::*; use ffi::OsString; diff --git a/src/libsyntax/errors/emitter.rs b/src/libsyntax/errors/emitter.rs index 486e2ace087..e7007fb0568 100644 --- a/src/libsyntax/errors/emitter.rs +++ b/src/libsyntax/errors/emitter.rs @@ -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; diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index c81198d4729..2c21fd2cd5e 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -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; diff --git a/src/test/compile-fail/dep-graph-trait-impl-two-traits-same-method.rs b/src/test/compile-fail/dep-graph-trait-impl-two-traits-same-method.rs index 1afecd80ff5..5e4f43af669 100644 --- a/src/test/compile-fail/dep-graph-trait-impl-two-traits-same-method.rs +++ b/src/test/compile-fail/dep-graph-trait-impl-two-traits-same-method.rs @@ -15,6 +15,7 @@ #![feature(rustc_attrs)] #![allow(dead_code)] +#![allow(unused_imports)] fn main() { } diff --git a/src/test/compile-fail/lint-unused-imports.rs b/src/test/compile-fail/lint-unused-imports.rs index 3c1f4b04306..40322f5a5b5 100644 --- a/src/test/compile-fail/lint-unused-imports.rs +++ b/src/test/compile-fail/lint-unused-imports.rs @@ -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 {} diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 7ad54c5bf6b..7e688b5ec6b 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -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 { diff --git a/src/tools/rustbook/main.rs b/src/tools/rustbook/main.rs index 5ad4982e8af..e0092f8e29e 100644 --- a/src/tools/rustbook/main.rs +++ b/src/tools/rustbook/main.rs @@ -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;