From a61126cef6c4083d57e22835033eb2eefdd31bac Mon Sep 17 00:00:00 2001 From: surechen Date: Fri, 10 Nov 2023 10:11:24 +0800 Subject: [PATCH] By tracking import use types to check whether it is scope uses or the other situations like module-relative uses, we can do more accurate redundant import checking. fixes #117448 For example unnecessary imports in std::prelude that can be eliminated: ```rust use std::option::Option::Some;//~ WARNING the item `Some` is imported redundantly use std::option::Option::None; //~ WARNING the item `None` is imported redundantly ``` --- .../rustc_data_structures/src/owned_slice.rs | 12 +-- .../rustc_hir_analysis/src/check/check.rs | 3 +- .../missing_cast_for_variadic_arg.rs | 2 +- .../structured_errors/sized_unsized_cast.rs | 2 +- .../wrong_number_of_generic_args.rs | 4 +- compiler/rustc_hir_typeck/src/expr.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- compiler/rustc_hir_typeck/src/lib.rs | 2 +- .../infer/error_reporting/need_type_info.rs | 2 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 2 +- compiler/rustc_middle/src/mir/syntax.rs | 2 +- .../rustc_resolve/src/build_reduced_graph.rs | 14 ++-- compiler/rustc_resolve/src/check_unused.rs | 46 +++++++++--- compiler/rustc_resolve/src/def_collector.rs | 2 +- compiler/rustc_resolve/src/diagnostics.rs | 4 +- compiler/rustc_resolve/src/ident.rs | 10 +-- compiler/rustc_resolve/src/imports.rs | 75 ++++++++++--------- compiler/rustc_resolve/src/late.rs | 13 ++-- compiler/rustc_resolve/src/lib.rs | 51 ++++++++++--- compiler/rustc_resolve/src/macros.rs | 4 +- compiler/rustc_session/src/session.rs | 2 +- compiler/rustc_span/src/source_map/tests.rs | 2 - library/std/src/os/unix/fs.rs | 1 - src/tools/clippy/src/driver.rs | 1 - .../crates/hir-def/src/body/pretty.rs | 2 +- .../crates/hir-def/src/import_map.rs | 2 +- .../crates/hir-def/src/item_tree/lower.rs | 8 +- .../crates/hir-def/src/item_tree/pretty.rs | 5 +- .../crates/hir-def/src/nameres.rs | 2 +- .../src/diagnostics/match_check/pat_util.rs | 2 +- .../crates/hir-ty/src/mir/eval/shim.rs | 6 +- .../crates/hir-ty/src/mir/lower.rs | 10 +-- .../hir-ty/src/mir/lower/pattern_matching.rs | 2 +- .../src/handlers/generate_delegate_methods.rs | 2 +- .../src/completions/item_list/trait_impl.rs | 2 +- .../crates/ide-db/src/symbol_index.rs | 2 +- .../rust-analyzer/src/cargo_target_spec.rs | 2 +- .../crates/rust-analyzer/src/cli/lsif.rs | 2 +- .../salsa/salsa-macros/src/query_group.rs | 1 - .../rust-analyzer/crates/salsa/src/debug.rs | 1 - .../rust-analyzer/crates/salsa/src/derived.rs | 1 - .../rust-analyzer/crates/salsa/src/input.rs | 1 - .../crates/salsa/src/interned.rs | 1 - tests/ui/lint/unused/lint-unused-imports.rs | 2 - .../ui/lint/unused/lint-unused-imports.stderr | 26 +------ .../use-redundant-prelude-rust-2015.rs | 19 +++++ .../use-redundant-prelude-rust-2015.stderr | 44 +++++++++++ .../use-redundant-prelude-rust-2021.rs | 11 +++ .../use-redundant-prelude-rust-2021.stderr | 26 +++++++ tests/ui/rust-2018/remove-extern-crate.fixed | 1 + tests/ui/rust-2018/remove-extern-crate.rs | 1 + tests/ui/rust-2018/remove-extern-crate.stderr | 6 +- 52 files changed, 283 insertions(+), 167 deletions(-) create mode 100644 tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.rs create mode 100644 tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr create mode 100644 tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs create mode 100644 tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr diff --git a/compiler/rustc_data_structures/src/owned_slice.rs b/compiler/rustc_data_structures/src/owned_slice.rs index cbb3047d884..bb664795860 100644 --- a/compiler/rustc_data_structures/src/owned_slice.rs +++ b/compiler/rustc_data_structures/src/owned_slice.rs @@ -4,7 +4,7 @@ use crate::sync::Lrc; // Use our fake Send/Sync traits when on not parallel compiler, // so that `OwnedSlice` only implements/requires Send/Sync // for parallel compiler builds. -use crate::sync::{Send, Sync}; +use crate::sync; /// An owned slice. /// @@ -33,7 +33,7 @@ pub struct OwnedSlice { // \/ // ⊂(´・◡・⊂ )∘˚˳° (I am the phantom remnant of #97770) #[expect(dead_code)] - owner: Lrc, + owner: Lrc, } /// Makes an [`OwnedSlice`] out of an `owner` and a `slicer` function. @@ -60,7 +60,7 @@ pub struct OwnedSlice { /// ``` pub fn slice_owned(owner: O, slicer: F) -> OwnedSlice where - O: Send + Sync + 'static, + O: sync::Send + sync::Sync + 'static, F: FnOnce(&O) -> &[u8], { try_slice_owned(owner, |x| Ok::<_, !>(slicer(x))).into_ok() @@ -71,7 +71,7 @@ where /// See [`slice_owned`] for the infallible version. pub fn try_slice_owned(owner: O, slicer: F) -> Result where - O: Send + Sync + 'static, + O: sync::Send + sync::Sync + 'static, F: FnOnce(&O) -> Result<&[u8], E>, { // We wrap the owner of the bytes in, so it doesn't move. @@ -139,11 +139,11 @@ impl Borrow<[u8]> for OwnedSlice { // Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Arc)`, which is `Send` #[cfg(parallel_compiler)] -unsafe impl Send for OwnedSlice {} +unsafe impl sync::Send for OwnedSlice {} // Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Arc)`, which is `Sync` #[cfg(parallel_compiler)] -unsafe impl Sync for OwnedSlice {} +unsafe impl sync::Sync for OwnedSlice {} #[cfg(test)] mod tests; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 1410273e3bc..0da417c6ea6 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -5,10 +5,9 @@ use super::compare_impl_item::check_type_bounds; use super::compare_impl_item::{compare_impl_method, compare_impl_ty}; use super::*; use rustc_attr as attr; -use rustc_errors::{codes::*, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{codes::*, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind}; -use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::Node; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, TraitEngineExt as _}; diff --git a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs index 50b4ef623ac..363b9ba6996 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs @@ -1,5 +1,5 @@ use crate::{errors, structured_errors::StructuredDiagnostic}; -use rustc_errors::{codes::*, DiagnosticBuilder, ErrCode}; +use rustc_errors::{codes::*, DiagnosticBuilder}; use rustc_middle::ty::{Ty, TypeVisitableExt}; use rustc_session::Session; use rustc_span::Span; diff --git a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs b/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs index 54d54a2af93..052c2807a2e 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs @@ -1,5 +1,5 @@ use crate::{errors, structured_errors::StructuredDiagnostic}; -use rustc_errors::{codes::*, DiagnosticBuilder, ErrCode}; +use rustc_errors::{codes::*, DiagnosticBuilder}; use rustc_middle::ty::{Ty, TypeVisitableExt}; use rustc_session::Session; use rustc_span::Span; diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 52ff8b2e45d..f9d57d402b1 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -1,7 +1,5 @@ use crate::structured_errors::StructuredDiagnostic; -use rustc_errors::{ - codes::*, pluralize, Applicability, Diagnostic, DiagnosticBuilder, ErrCode, MultiSpan, -}; +use rustc_errors::{codes::*, pluralize, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan}; use rustc_hir as hir; use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt}; use rustc_session::Session; diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index ed19d00d641..a946d59ff2b 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -27,7 +27,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::unord::UnordMap; use rustc_errors::{ codes::*, pluralize, struct_span_code_err, AddToDiagnostic, Applicability, Diagnostic, - DiagnosticBuilder, ErrCode, ErrorGuaranteed, StashKey, + DiagnosticBuilder, ErrorGuaranteed, StashKey, }; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index dd527666d55..d8d3d45dd40 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -13,7 +13,7 @@ use itertools::Itertools; use rustc_ast as ast; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{ - codes::*, pluralize, Applicability, Diagnostic, ErrCode, ErrorGuaranteed, MultiSpan, StashKey, + codes::*, pluralize, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey, }; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 629c2f2a971..70ddd6b2f4c 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -53,7 +53,7 @@ use crate::expectation::Expectation; use crate::fn_ctxt::LoweredTy; use crate::gather_locals::GatherLocalsVisitor; use rustc_data_structures::unord::UnordSet; -use rustc_errors::{codes::*, struct_span_code_err, ErrCode, ErrorGuaranteed}; +use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::Visitor; diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index c637ab31cd2..af722b20626 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -5,7 +5,7 @@ use crate::errors::{ use crate::infer::error_reporting::TypeErrCtxt; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::InferCtxt; -use rustc_errors::{codes::*, DiagnosticBuilder, ErrCode, IntoDiagnosticArg}; +use rustc_errors::{codes::*, DiagnosticBuilder, IntoDiagnosticArg}; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def::{CtorOf, DefKind, Namespace}; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 2cfbaff35ef..e7c80639a0d 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -13,7 +13,7 @@ use rustc_data_structures::unhash::UnhashMap; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro}; use rustc_hir::def::Res; -use rustc_hir::def_id::{DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefPath, DefPathData}; use rustc_hir::diagnostic_items::DiagnosticItems; use rustc_index::Idx; diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 40af453f6ce..5c9857b9c53 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -15,7 +15,7 @@ use crate::ty::{Region, UserTypeAnnotationIndex}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_data_structures::packed::Pu128; use rustc_hir::def_id::DefId; -use rustc_hir::{self, CoroutineKind}; +use rustc_hir::CoroutineKind; use rustc_index::IndexVec; use rustc_span::source_map::Spanned; use rustc_target::abi::{FieldIdx, VariantIdx}; diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 469d15e4214..1c4aeefcbcf 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -8,11 +8,11 @@ use crate::def_collector::collect_definitions; use crate::imports::{ImportData, ImportKind}; use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; -use crate::Namespace::{self, MacroNS, TypeNS, ValueNS}; +use crate::Namespace::{MacroNS, TypeNS, ValueNS}; use crate::{errors, BindingKey, MacroData, NameBindingData}; use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot}; -use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError}; -use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, VisResolutionError}; +use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, ResolutionError}; +use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, Used, VisResolutionError}; use rustc_ast::visit::{self, AssocCtxt, Visitor}; use rustc_ast::{self as ast, AssocItem, AssocItemKind, MetaItemKind, StmtKind}; @@ -362,7 +362,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { root_span, root_id, vis: Cell::new(Some(vis)), - used: Cell::new(false), + used: Default::default(), }); self.r.indeterminate_imports.push(import); @@ -885,7 +885,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { span: item.span, module_path: Vec::new(), vis: Cell::new(Some(vis)), - used: Cell::new(used), + used: Cell::new(used.then_some(Used::Other)), }); self.r.potentially_unused_imports.push(import); let imported_binding = self.r.import(binding, import); @@ -1090,7 +1090,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { span, module_path: Vec::new(), vis: Cell::new(Some(ty::Visibility::Restricted(CRATE_DEF_ID))), - used: Cell::new(false), + used: Default::default(), }) }; @@ -1261,7 +1261,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { span, module_path: Vec::new(), vis: Cell::new(Some(vis)), - used: Cell::new(true), + used: Cell::new(Some(Used::Other)), }); let import_binding = self.r.import(binding, import); self.r.define(self.r.graph_root, ident, MacroNS, import_binding); diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index c14788b841d..37cc50f6943 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -27,9 +27,10 @@ use crate::imports::ImportKind; use crate::module_to_string; use crate::Resolver; +use crate::NameBindingKind; use rustc_ast as ast; use rustc_ast::visit::{self, Visitor}; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::unord::UnordSet; use rustc_errors::{pluralize, MultiSpan}; use rustc_hir::def::{DefKind, Res}; @@ -38,14 +39,14 @@ use rustc_session::lint::BuiltinLintDiagnostics; use rustc_span::symbol::{kw, Ident}; use rustc_span::{Span, DUMMY_SP}; -struct UnusedImport<'a> { - use_tree: &'a ast::UseTree, +struct UnusedImport { + use_tree: ast::UseTree, use_tree_id: ast::NodeId, item_span: Span, unused: UnordSet, } -impl<'a> UnusedImport<'a> { +impl UnusedImport { fn add(&mut self, id: ast::NodeId) { self.unused.insert(id); } @@ -54,7 +55,7 @@ impl<'a> UnusedImport<'a> { struct UnusedImportCheckVisitor<'a, 'b, 'tcx> { r: &'a mut Resolver<'b, 'tcx>, /// All the (so far) unused imports, grouped path list - unused_imports: FxIndexMap>, + unused_imports: FxIndexMap, extern_crate_items: Vec, base_use_tree: Option<&'a ast::UseTree>, base_id: ast::NodeId, @@ -100,9 +101,9 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { } } - fn unused_import(&mut self, id: ast::NodeId) -> &mut UnusedImport<'a> { + fn unused_import(&mut self, id: ast::NodeId) -> &mut UnusedImport { let use_tree_id = self.base_id; - let use_tree = self.base_use_tree.unwrap(); + let use_tree = self.base_use_tree.unwrap().clone(); let item_span = self.item_span; self.unused_imports.entry(id).or_insert_with(|| UnusedImport { @@ -197,7 +198,7 @@ enum UnusedSpanResult { } fn calc_unused_spans( - unused_import: &UnusedImport<'_>, + unused_import: &UnusedImport, use_tree: &ast::UseTree, use_tree_id: ast::NodeId, ) -> UnusedSpanResult { @@ -287,7 +288,7 @@ impl Resolver<'_, '_> { for import in self.potentially_unused_imports.iter() { match import.kind { - _ if import.used.get() + _ if import.used.get().is_some() || import.expect_vis().is_public() || import.span.is_dummy() => { @@ -336,7 +337,7 @@ impl Resolver<'_, '_> { for unused in visitor.unused_imports.values() { let mut fixes = Vec::new(); - let spans = match calc_unused_spans(unused, unused.use_tree, unused.use_tree_id) { + let spans = match calc_unused_spans(unused, &unused.use_tree, unused.use_tree_id) { UnusedSpanResult::Used => continue, UnusedSpanResult::FlatUnused(span, remove) => { fixes.push((remove, String::new())); @@ -483,5 +484,30 @@ impl Resolver<'_, '_> { BuiltinLintDiagnostics::ExternCrateNotIdiomatic { vis_span, ident_span }, ); } + + let unused_imports = visitor.unused_imports; + let mut check_redundant_imports = FxIndexSet::default(); + for module in self.arenas.local_modules().iter() { + for (_key, resolution) in self.resolutions(*module).borrow().iter() { + let resolution = resolution.borrow(); + + if let Some(binding) = resolution.binding + && let NameBindingKind::Import { import, .. } = binding.kind + && let ImportKind::Single { id, .. } = import.kind + { + if let Some(unused_import) = unused_imports.get(&import.root_id) + && unused_import.unused.contains(&id) + { + continue; + } + + check_redundant_imports.insert(import); + } + } + } + + for import in check_redundant_imports { + self.check_for_redundant_imports(import); + } } } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 45aea585f97..12bf462a6fd 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -1,5 +1,5 @@ use crate::{ImplTraitContext, Resolver}; -use rustc_ast::visit::{self, FnKind}; +use rustc_ast::visit::FnKind; use rustc_ast::*; use rustc_expand::expand::AstFragment; use rustc_hir::def::{CtorKind, CtorOf, DefKind}; diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 737481c78db..4b978fefa10 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -33,8 +33,8 @@ use crate::errors::{AddedMacroUse, ChangeImportBinding, ChangeImportBindingSugge use crate::errors::{ConsiderAddingADerive, ExplicitUnsafeTraits, MaybeMissingMacroRulesName}; use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; -use crate::path_names_to_string; use crate::{errors as errs, BindingKey}; +use crate::{path_names_to_string, Used}; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, Finalize}; use crate::{HasGenericParams, MacroRulesScope, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{LexicalScopeBinding, NameBinding, NameBindingKind, PrivacyError, VisResolutionError}; @@ -1503,7 +1503,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ); // Silence the 'unused import' warning we might get, // since this diagnostic already covers that import. - self.record_use(ident, binding, false); + self.record_use(ident, binding, Used::Other); return; } } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index e47f2bdd4d2..4583f991cab 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -12,8 +12,8 @@ use rustc_span::Span; use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind}; use crate::macros::{sub_namespace_match, MacroRulesScope}; -use crate::BindingKey; use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize}; +use crate::{BindingKey, Used}; use crate::{ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res}; use crate::{ResolutionError, Resolver, Scope, ScopeSet, Segment, ToNameBinding, Weak}; @@ -339,7 +339,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ident, ns, parent_scope, - finalize, + finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }), ignore_binding, ); if let Ok(binding) = item { @@ -506,7 +506,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ns, adjusted_parent_scope, !matches!(scope_set, ScopeSet::Late(..)), - finalize, + finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }), ignore_binding, ); match binding { @@ -857,7 +857,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .into_iter() .find_map(|binding| if binding == ignore_binding { None } else { binding }); - if let Some(Finalize { path_span, report_private, .. }) = finalize { + if let Some(Finalize { path_span, report_private, used, .. }) = finalize { let Some(binding) = binding else { return Err((Determined, Weak::No)); }; @@ -901,7 +901,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - self.record_use(ident, binding, restricted_shadowing); + self.record_use(ident, binding, used); return Ok(binding); } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index dcd01b9b334..9bfca0f1798 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -10,9 +10,9 @@ use crate::errors::{ use crate::Determinacy::{self, *}; use crate::Namespace::*; use crate::{module_to_string, names_to_string, ImportSuggestion}; -use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment}; +use crate::{AmbiguityKind, BindingKey, ResolutionError, Resolver, Segment}; use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet}; -use crate::{NameBinding, NameBindingData, NameBindingKind, PathResult}; +use crate::{NameBinding, NameBindingData, NameBindingKind, PathResult, Used}; use rustc_ast::NodeId; use rustc_data_structures::fx::FxHashSet; @@ -173,7 +173,7 @@ pub(crate) struct ImportData<'a> { /// The resolution of `module_path`. pub imported_module: Cell>>, pub vis: Cell>, - pub used: Cell, + pub used: Cell>, } /// All imports are unique and allocated on a same arena, @@ -286,7 +286,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } self.arenas.alloc_name_binding(NameBindingData { - kind: NameBindingKind::Import { binding, import, used: Cell::new(false) }, + kind: NameBindingKind::Import { binding, import }, ambiguity: None, warn_ambiguity: false, span: import.span, @@ -485,9 +485,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { resolution.single_imports.remove(&import); }) }); - self.record_use(target, dummy_binding, false); + self.record_use(target, dummy_binding, Used::Other); } else if import.imported_module.get().is_none() { - import.used.set(true); + import.used.set(Some(Used::Other)); if let Some(id) = import.id() { self.used_imports.insert(id); } @@ -1056,11 +1056,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { && initial_binding.is_extern_crate() && !initial_binding.is_import() { - this.record_use( - ident, - target_binding, - import.module_path.is_empty(), - ); + let used = if import.module_path.is_empty() { + Used::Scope + } else { + Used::Other + }; + this.record_use(ident, target_binding, used); } } initial_binding.res() @@ -1299,22 +1300,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } }); - self.check_for_redundant_imports(ident, import, source_bindings, target_bindings, target); - debug!("(resolving single import) successfully resolved import"); None } - fn check_for_redundant_imports( - &mut self, - ident: Ident, - import: Import<'a>, - source_bindings: &PerNS, Determinacy>>>, - target_bindings: &PerNS>>>, - target: Ident, - ) { + pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'a>) { // This function is only called for single imports. - let ImportKind::Single { id, .. } = import.kind else { unreachable!() }; + let ImportKind::Single { + source, target, ref source_bindings, ref target_bindings, id, .. + } = import.kind + else { + unreachable!() + }; + + // Skip if the import is of the form `use source as target` and source != target. + if source != target { + return; + } // Skip if the import was produced by a macro. if import.parent_scope.expansion != LocalExpnId::ROOT { @@ -1323,16 +1325,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Skip if we are inside a named module (in contrast to an anonymous // module defined by a block). - if let ModuleKind::Def(..) = import.parent_scope.module.kind { + // Skip if the import is public or was used through non scope-based resolution, + // e.g. through a module-relative path. + if import.used.get() == Some(Used::Other) + || self.effective_visibilities.is_exported(self.local_def_id(id)) + { return; } - let mut is_redundant = PerNS { value_ns: None, type_ns: None, macro_ns: None }; + let mut is_redundant = true; let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None }; self.per_ns(|this, ns| { - if let Ok(binding) = source_bindings[ns].get() { + if is_redundant && let Ok(binding) = source_bindings[ns].get() { if binding.res() == Res::Err { return; } @@ -1346,18 +1352,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { target_bindings[ns].get(), ) { Ok(other_binding) => { - is_redundant[ns] = Some( - binding.res() == other_binding.res() && !other_binding.is_ambiguity(), - ); - redundant_span[ns] = Some((other_binding.span, other_binding.is_import())); + is_redundant = + binding.res() == other_binding.res() && !other_binding.is_ambiguity(); + if is_redundant { + redundant_span[ns] = + Some((other_binding.span, other_binding.is_import())); + } } - Err(_) => is_redundant[ns] = Some(false), + Err(_) => is_redundant = false, } } }); - if !is_redundant.is_empty() && is_redundant.present_items().all(|is_redundant| is_redundant) - { + if is_redundant && !redundant_span.is_empty() { let mut redundant_spans: Vec<_> = redundant_span.present_items().collect(); redundant_spans.sort(); redundant_spans.dedup(); @@ -1365,8 +1372,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { UNUSED_IMPORTS, id, import.span, - format!("the item `{ident}` is imported redundantly"), - BuiltinLintDiagnostics::RedundantImport(redundant_spans, ident), + format!("the item `{source}` is imported redundantly"), + BuiltinLintDiagnostics::RedundantImport(redundant_spans, source), ); } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 3ea4df1d2a4..1cf3fecc289 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -7,23 +7,22 @@ //! `build_reduced_graph.rs`, `macros.rs` and `imports.rs`. use crate::errors::ImportsCannotReferTo; -use crate::BindingKey; use crate::{path_names_to_string, rustdoc, BindingError, Finalize, LexicalScopeBinding}; +use crate::{BindingKey, Used}; use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult}; use crate::{ResolutionError, Resolver, Segment, UseError}; use rustc_ast::ptr::P; -use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor}; +use rustc_ast::visit::{AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor}; use rustc_ast::*; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_errors::{ - codes::*, struct_span_code_err, Applicability, DiagnosticArgValue, ErrCode, IntoDiagnosticArg, - StashKey, + codes::*, struct_span_code_err, Applicability, DiagnosticArgValue, IntoDiagnosticArg, StashKey, }; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; -use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate}; +use rustc_hir::{PrimTy, TraitCandidate}; use rustc_metadata::creader::CStore; use rustc_middle::middle::resolve_bound_vars::Set1; use rustc_middle::{bug, span_bug}; @@ -3623,7 +3622,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // whether they can be shadowed by fresh bindings or not, so force an error. // issues/33118#issuecomment-233962221 (see below) still applies here, // but we have to ignore it for backward compatibility. - self.r.record_use(ident, binding, false); + self.r.record_use(ident, binding, Used::Other); return None; } LexicalScopeBinding::Item(binding) => (binding.res(), Some(binding)), @@ -3638,7 +3637,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ) if is_syntactic_ambiguity => { // Disambiguate in favor of a unit struct/variant or constant pattern. if let Some(binding) = binding { - self.r.record_use(ident, binding, false); + self.r.record_use(ident, binding, Used::Other); } Some(res) } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index bf811c7a4bb..1c625f49e3e 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -175,6 +175,23 @@ enum ImplTraitContext { Universal, } +/// Used for tracking import use types which will be used for redundant import checking. +/// ### Used::Scope Example +/// ```rust,compile_fail +/// #![deny(unused_imports)] +/// use std::mem::drop; +/// fn main() { +/// let s = Box::new(32); +/// drop(s); +/// } +/// ``` +/// Used::Other is for other situations like module-relative uses. +#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] +enum Used { + Scope, + Other, +} + #[derive(Debug)] struct BindingError { name: Symbol, @@ -695,7 +712,7 @@ impl<'a> ToNameBinding<'a> for NameBinding<'a> { enum NameBindingKind<'a> { Res(Res), Module(Module<'a>), - Import { binding: NameBinding<'a>, import: Import<'a>, used: Cell }, + Import { binding: NameBinding<'a>, import: Import<'a> }, } impl<'a> NameBindingKind<'a> { @@ -1784,15 +1801,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { false } - fn record_use(&mut self, ident: Ident, used_binding: NameBinding<'a>, is_lexical_scope: bool) { - self.record_use_inner(ident, used_binding, is_lexical_scope, used_binding.warn_ambiguity); + fn record_use(&mut self, ident: Ident, used_binding: NameBinding<'a>, used: Used) { + self.record_use_inner(ident, used_binding, used, used_binding.warn_ambiguity); } fn record_use_inner( &mut self, ident: Ident, used_binding: NameBinding<'a>, - is_lexical_scope: bool, + used: Used, warn_ambiguity: bool, ) { if let Some((b2, kind)) = used_binding.ambiguity { @@ -1810,27 +1827,35 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.ambiguity_errors.push(ambiguity_error); } } - if let NameBindingKind::Import { import, binding, ref used } = used_binding.kind { + if let NameBindingKind::Import { import, binding } = used_binding.kind { if let ImportKind::MacroUse { warn_private: true } = import.kind { let msg = format!("macro `{ident}` is private"); self.lint_buffer().buffer_lint(PRIVATE_MACRO_USE, import.root_id, ident.span, msg); } // Avoid marking `extern crate` items that refer to a name from extern prelude, // but not introduce it, as used if they are accessed from lexical scope. - if is_lexical_scope { + if used == Used::Scope { if let Some(entry) = self.extern_prelude.get(&ident.normalize_to_macros_2_0()) { if !entry.introduced_by_item && entry.binding == Some(used_binding) { return; } } } - used.set(true); - import.used.set(true); + let old_used = import.used.get(); + let new_used = Some(used); + if new_used > old_used { + import.used.set(new_used); + } if let Some(id) = import.id() { self.used_imports.insert(id); } self.add_to_glob_map(import, ident); - self.record_use_inner(ident, binding, false, warn_ambiguity || binding.warn_ambiguity); + self.record_use_inner( + ident, + binding, + Used::Other, + warn_ambiguity || binding.warn_ambiguity, + ); } } @@ -1985,7 +2010,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if !entry.is_import() { self.crate_loader(|c| c.process_path_extern(ident.name, ident.span)); } else if entry.introduced_by_item { - self.record_use(ident, binding, false); + self.record_use(ident, binding, Used::Other); } } binding @@ -2115,7 +2140,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let is_import = name_binding.is_import(); let span = name_binding.span; if let Res::Def(DefKind::Fn, _) = res { - self.record_use(ident, name_binding, false); + self.record_use(ident, name_binding, Used::Other); } self.main_def = Some(MainDefinition { res, is_import, span }); } @@ -2176,6 +2201,8 @@ struct Finalize { /// Whether to report privacy errors or silently return "no resolution" for them, /// similarly to speculative resolution. report_private: bool, + /// Tracks whether an item is used in scope or used relatively to a module. + used: Used, } impl Finalize { @@ -2184,7 +2211,7 @@ impl Finalize { } fn with_root_span(node_id: NodeId, path_span: Span, root_span: Span) -> Finalize { - Finalize { node_id, path_span, root_span, report_private: true } + Finalize { node_id, path_span, root_span, report_private: true, used: Used::Other } } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 170cc1268c3..3fccdec8aa0 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -5,7 +5,7 @@ use crate::errors::CannotDetermineMacroResolution; use crate::errors::{self, AddAsNonDerive, CannotFindIdentInThisScope}; use crate::errors::{MacroExpectedFound, RemoveSurroundingDerive}; use crate::Namespace::*; -use crate::{BuiltinMacroState, Determinacy, MacroData}; +use crate::{BuiltinMacroState, Determinacy, MacroData, Used}; use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet}; use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding}; use rustc_ast::expand::StrippedCfgItem; @@ -794,7 +794,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ) { Ok(binding) => { let initial_res = initial_binding.map(|initial_binding| { - self.record_use(ident, initial_binding, false); + self.record_use(ident, initial_binding, Used::Other); initial_binding.res() }); let res = binding.res(); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 25c20be8e62..9d1133c487f 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -22,7 +22,7 @@ use rustc_errors::emitter::{DynEmitter, HumanEmitter, HumanReadableErrorType}; use rustc_errors::json::JsonEmitter; use rustc_errors::registry::Registry; use rustc_errors::{ - codes::*, fallback_fluent_bundle, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, ErrCode, + codes::*, fallback_fluent_bundle, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, FatalAbort, FluentBundle, IntoDiagnostic, LazyFallbackBundle, TerminalUrl, }; use rustc_macros::HashStable_Generic; diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs index 51f8aa04e8a..81a9e470688 100644 --- a/compiler/rustc_span/src/source_map/tests.rs +++ b/compiler/rustc_span/src/source_map/tests.rs @@ -1,7 +1,5 @@ use super::*; -use rustc_data_structures::sync::FreezeLock; - fn init_source_map() -> SourceMap { let sm = SourceMap::new(FilePathMapping::empty()); sm.new_source_file(PathBuf::from("blork.rs").into(), "first line.\nsecond line".to_string()); diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs index e995d5133f8..058e9b90cc7 100644 --- a/library/std/src/os/unix/fs.rs +++ b/library/std/src/os/unix/fs.rs @@ -397,7 +397,6 @@ pub trait OpenOptionsExt { /// /// ```no_run /// # #![feature(rustc_private)] - /// use libc; /// use std::fs::OpenOptions; /// use std::os::unix::fs::OpenOptionsExt; /// diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index bdf1cf0a224..85867d1511d 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -28,7 +28,6 @@ use std::fs::read_to_string; use std::ops::Deref; use std::path::Path; use std::process::exit; -use std::string::ToString; use anstream::println; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs index 4afb4086517..6afb46a2ddd 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs @@ -6,7 +6,7 @@ use itertools::Itertools; use crate::{ hir::{ - Array, BindingAnnotation, BindingId, CaptureBy, ClosureKind, Literal, LiteralOrConst, + Array, BindingAnnotation, CaptureBy, ClosureKind, Literal, LiteralOrConst, Movability, Statement, }, pretty::{print_generic_args, print_path, print_type_ref}, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index 98982c7db84..38cfcf0f281 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs @@ -3,7 +3,7 @@ use std::{fmt, hash::BuildHasherDefault}; use base_db::CrateId; -use fst::{self, raw::IndexedValue, Automaton, Streamer}; +use fst::{raw::IndexedValue, Automaton, Streamer}; use hir_expand::name::Name; use indexmap::IndexMap; use itertools::Itertools; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index e0aa3ae6123..b51cb5de0f4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs @@ -2,12 +2,12 @@ use std::collections::hash_map::Entry; -use hir_expand::{ast_id_map::AstIdMap, span_map::SpanMapRef, HirFileId}; -use syntax::ast::{self, HasModuleItem, HasTypeBounds, IsString}; +use hir_expand::{ast_id_map::AstIdMap, span_map::SpanMapRef}; +use syntax::ast::{HasModuleItem, HasTypeBounds, IsString}; use crate::{ - generics::{GenericParams, GenericParamsCollector, TypeParamData, TypeParamProvenance}, - type_ref::{LifetimeRef, TraitBoundModifier, TraitRef}, + generics::{GenericParamsCollector, TypeParamData, TypeParamProvenance}, + type_ref::{LifetimeRef, TraitBoundModifier}, LocalLifetimeParamId, LocalTypeOrConstParamId, }; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs index 0086b7180b2..dae876f7ecb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs @@ -1,13 +1,12 @@ //! `ItemTree` debug printer. -use std::fmt::{self, Write}; +use std::fmt::Write; use span::ErasedFileAstId; use crate::{ - generics::{TypeOrConstParamData, WherePredicate, WherePredicateTypeTarget}, + generics::{WherePredicate, WherePredicateTypeTarget}, pretty::{print_path, print_type_bounds, print_type_ref}, - visibility::RawVisibility, }; use super::*; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index 2a9390e7978..a2eca066438 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -57,7 +57,7 @@ pub mod proc_macro; #[cfg(test)] mod tests; -use std::{cmp::Ord, ops::Deref}; +use std::ops::Deref; use base_db::{CrateId, Edition, FileId}; use hir_expand::{ diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_util.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_util.rs index 217454499ef..c6a26cdd1d0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_util.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_util.rs @@ -2,7 +2,7 @@ //! //! Originates from `rustc_hir::pat_util` -use std::iter::{Enumerate, ExactSizeIterator}; +use std::iter::Enumerate; pub(crate) struct EnumerateAndAdjust { enumerate: Enumerate, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index d68803fe280..fbe6a982d6f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -4,11 +4,7 @@ use std::cmp; use chalk_ir::TyKind; -use hir_def::{ - builtin_type::{BuiltinInt, BuiltinUint}, - resolver::HasResolver, -}; -use hir_expand::mod_path::ModPath; +use hir_def::builtin_type::{BuiltinInt, BuiltinUint}; use super::*; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 1572a6d497c..f0cb0afd5ac 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -1,6 +1,6 @@ //! This module generates a polymorphic MIR from a hir body -use std::{fmt::Write, iter, mem}; +use std::{fmt::Write, mem}; use base_db::{salsa::Cycle, FileId}; use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind}; @@ -14,23 +14,19 @@ use hir_def::{ lang_item::{LangItem, LangItemTarget}, path::Path, resolver::{resolver_for_expr, HasResolver, ResolveValueResult, ValueNs}, - AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId, + AdtId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId, Lookup, TraitId, TupleId, TypeOrConstParamId, }; use hir_expand::name::Name; -use la_arena::ArenaMap; -use rustc_hash::FxHashMap; use syntax::TextRange; use triomphe::Arc; use crate::{ consteval::ConstEvalError, - db::{HirDatabase, InternedClosure}, - display::HirDisplay, + db::InternedClosure, infer::{CaptureKind, CapturedItem, TypeMismatch}, inhabitedness::is_ty_uninhabited_from, layout::LayoutError, - mapping::ToChalk, static_lifetime, traits::FnTrait, utils::{generics, ClosureSubst}, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs index 8202bac532f..02b1494062f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs @@ -1,6 +1,6 @@ //! MIR lowering for patterns -use hir_def::{hir::LiteralOrConst, resolver::HasResolver, AssocItemId}; +use hir_def::AssocItemId; use crate::BindingMode; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs index 4f2df5633c3..38f40b8d58b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs @@ -1,4 +1,4 @@ -use hir::{self, HasCrate, HasVisibility}; +use hir::{HasCrate, HasVisibility}; use ide_db::{path_transform::PathTransform, FxHashSet}; use syntax::{ ast::{ diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs index 3c4b89ca742..7394d63be58 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -31,7 +31,7 @@ //! } //! ``` -use hir::{self, HasAttrs}; +use hir::HasAttrs; use ide_db::{ documentation::HasDocs, path_transform::PathTransform, syntax_helpers::insert_whitespace_into_node, traits::get_missing_assoc_items, SymbolKind, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs index 92c09089e1f..722161282fe 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs @@ -31,7 +31,7 @@ use base_db::{ salsa::{self, ParallelDatabase}, SourceDatabaseExt, SourceRootId, Upcast, }; -use fst::{self, raw::IndexedValue, Automaton, Streamer}; +use fst::{raw::IndexedValue, Automaton, Streamer}; use hir::{ db::HirDatabase, import_map::{AssocSearchMode, SearchMode}, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cargo_target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cargo_target_spec.rs index 0190ca3cab8..879e259d0e4 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cargo_target_spec.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cargo_target_spec.rs @@ -4,7 +4,7 @@ use std::mem; use cfg::{CfgAtom, CfgExpr}; use ide::{Cancellable, CrateId, FileId, RunnableKind, TestId}; -use project_model::{self, CargoFeatures, ManifestPath, TargetKind}; +use project_model::{CargoFeatures, ManifestPath, TargetKind}; use rustc_hash::FxHashSet; use vfs::AbsPathBuf; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs index 1424a775777..5e810463db6 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs @@ -13,7 +13,7 @@ use ide_db::{ LineIndexDatabase, }; use load_cargo::{load_workspace, LoadCargoConfig, ProcMacroServerChoice}; -use lsp_types::{self, lsif}; +use lsp_types::lsif; use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace, RustLibSource}; use rustc_hash::FxHashMap; use vfs::{AbsPathBuf, Vfs}; diff --git a/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/query_group.rs b/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/query_group.rs index e535d7ed043..5d1678ef120 100644 --- a/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/query_group.rs +++ b/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/query_group.rs @@ -1,5 +1,4 @@ //! -use std::{convert::TryFrom, iter::FromIterator}; use crate::parenthesized::Parenthesized; use heck::ToUpperCamelCase; diff --git a/src/tools/rust-analyzer/crates/salsa/src/debug.rs b/src/tools/rust-analyzer/crates/salsa/src/debug.rs index 0925ddb3d85..5f113541f04 100644 --- a/src/tools/rust-analyzer/crates/salsa/src/debug.rs +++ b/src/tools/rust-analyzer/crates/salsa/src/debug.rs @@ -5,7 +5,6 @@ use crate::durability::Durability; use crate::plumbing::QueryStorageOps; use crate::Query; use crate::QueryTable; -use std::iter::FromIterator; /// Additional methods on queries that can be used to "peek into" /// their current state. These methods are meant for debugging and diff --git a/src/tools/rust-analyzer/crates/salsa/src/derived.rs b/src/tools/rust-analyzer/crates/salsa/src/derived.rs index c381e66e087..d6316710058 100644 --- a/src/tools/rust-analyzer/crates/salsa/src/derived.rs +++ b/src/tools/rust-analyzer/crates/salsa/src/derived.rs @@ -13,7 +13,6 @@ use crate::Runtime; use crate::{Database, DatabaseKeyIndex, QueryDb, Revision}; use parking_lot::RwLock; use std::borrow::Borrow; -use std::convert::TryFrom; use std::hash::Hash; use std::marker::PhantomData; use triomphe::Arc; diff --git a/src/tools/rust-analyzer/crates/salsa/src/input.rs b/src/tools/rust-analyzer/crates/salsa/src/input.rs index 4e8fca6149b..c2539570e0f 100644 --- a/src/tools/rust-analyzer/crates/salsa/src/input.rs +++ b/src/tools/rust-analyzer/crates/salsa/src/input.rs @@ -14,7 +14,6 @@ use crate::Runtime; use crate::{DatabaseKeyIndex, QueryDb}; use indexmap::map::Entry; use parking_lot::RwLock; -use std::convert::TryFrom; use std::iter; use tracing::debug; diff --git a/src/tools/rust-analyzer/crates/salsa/src/interned.rs b/src/tools/rust-analyzer/crates/salsa/src/interned.rs index 731839e9598..822219f5185 100644 --- a/src/tools/rust-analyzer/crates/salsa/src/interned.rs +++ b/src/tools/rust-analyzer/crates/salsa/src/interned.rs @@ -13,7 +13,6 @@ use crate::{Database, DatabaseKeyIndex, QueryDb}; use parking_lot::RwLock; use rustc_hash::FxHashMap; use std::collections::hash_map::Entry; -use std::convert::From; use std::fmt::Debug; use std::hash::Hash; use triomphe::Arc; diff --git a/tests/ui/lint/unused/lint-unused-imports.rs b/tests/ui/lint/unused/lint-unused-imports.rs index 4fa6511c97e..88f2baa5da9 100644 --- a/tests/ui/lint/unused/lint-unused-imports.rs +++ b/tests/ui/lint/unused/lint-unused-imports.rs @@ -66,7 +66,6 @@ pub mod bar { fn g() { use self::g; //~ ERROR unused import: `self::g` - //~^ ERROR the item `g` is imported redundantly fn f() { self::g(); } @@ -76,7 +75,6 @@ fn g() { #[allow(unused_variables)] fn h() { use test2::foo; //~ ERROR unused import: `test2::foo` - //~^ ERROR the item `foo` is imported redundantly let foo = 0; } diff --git a/tests/ui/lint/unused/lint-unused-imports.stderr b/tests/ui/lint/unused/lint-unused-imports.stderr index 0574ca4569f..07684a84a64 100644 --- a/tests/ui/lint/unused/lint-unused-imports.stderr +++ b/tests/ui/lint/unused/lint-unused-imports.stderr @@ -34,36 +34,14 @@ error: unused import: `foo::Square` LL | use foo::Square; | ^^^^^^^^^^^ -error: the item `g` is imported redundantly - --> $DIR/lint-unused-imports.rs:68:9 - | -LL | / fn g() { -LL | | use self::g; - | | ^^^^^^^ -LL | | -LL | | fn f() { -LL | | self::g(); -LL | | } -LL | | } - | |_- the item `g` is already defined here - error: unused import: `self::g` --> $DIR/lint-unused-imports.rs:68:9 | LL | use self::g; | ^^^^^^^ -error: the item `foo` is imported redundantly - --> $DIR/lint-unused-imports.rs:78:9 - | -LL | use test2::{foo, bar}; - | --- the item `foo` is already imported here -... -LL | use test2::foo; - | ^^^^^^^^^^ - error: unused import: `test2::foo` - --> $DIR/lint-unused-imports.rs:78:9 + --> $DIR/lint-unused-imports.rs:77:9 | LL | use test2::foo; | ^^^^^^^^^^ @@ -74,5 +52,5 @@ error: unused import: `test::B2` LL | use test::B2; | ^^^^^^^^ -error: aborting due to 10 previous errors +error: aborting due to 8 previous errors diff --git a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.rs b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.rs new file mode 100644 index 00000000000..ae5118b2729 --- /dev/null +++ b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.rs @@ -0,0 +1,19 @@ +//@ check-pass +#![warn(unused_imports)] + + +use std::option::Option::Some;//~ WARNING the item `Some` is imported redundantly +use std::option::Option::None; //~ WARNING the item `None` is imported redundantly + +use std::result::Result::Ok;//~ WARNING the item `Ok` is imported redundantly +use std::result::Result::Err;//~ WARNING the item `Err` is imported redundantly +use std::convert::{TryFrom, TryInto}; + +fn main() { + let _a: Option = Some(1); + let _b: Option = None; + let _c: Result = Ok(1); + let _d: Result = Err("error"); + let _e: Result = 8u8.try_into(); + let _f: Result = i32::try_from(8u8); +} diff --git a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr new file mode 100644 index 00000000000..1b09df911eb --- /dev/null +++ b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr @@ -0,0 +1,44 @@ +warning: the item `Some` is imported redundantly + --> $DIR/use-redundant-prelude-rust-2015.rs:5:5 + | +LL | use std::option::Option::Some; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + | + = note: the item `Some` is already defined here + | +note: the lint level is defined here + --> $DIR/use-redundant-prelude-rust-2015.rs:2:9 + | +LL | #![warn(unused_imports)] + | ^^^^^^^^^^^^^^ + +warning: the item `None` is imported redundantly + --> $DIR/use-redundant-prelude-rust-2015.rs:6:5 + | +LL | use std::option::Option::None; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + | + = note: the item `None` is already defined here + +warning: the item `Ok` is imported redundantly + --> $DIR/use-redundant-prelude-rust-2015.rs:8:5 + | +LL | use std::result::Result::Ok; + | ^^^^^^^^^^^^^^^^^^^^^^^ + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + | + = note: the item `Ok` is already defined here + +warning: the item `Err` is imported redundantly + --> $DIR/use-redundant-prelude-rust-2015.rs:9:5 + | +LL | use std::result::Result::Err; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + | + = note: the item `Err` is already defined here + +warning: 4 warnings emitted + diff --git a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs new file mode 100644 index 00000000000..cb4dcb6c0bd --- /dev/null +++ b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs @@ -0,0 +1,11 @@ +//@ check-pass +//@ edition:2021 +#![warn(unused_imports)] + +use std::convert::TryFrom;//~ WARNING the item `TryFrom` is imported redundantly +use std::convert::TryInto;//~ WARNING the item `TryInto` is imported redundantly + +fn main() { + let _e: Result = 8u8.try_into(); + let _f: Result = i32::try_from(8u8); +} diff --git a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr new file mode 100644 index 00000000000..542356dc996 --- /dev/null +++ b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr @@ -0,0 +1,26 @@ +warning: the item `TryFrom` is imported redundantly + --> $DIR/use-redundant-prelude-rust-2021.rs:5:5 + | +LL | use std::convert::TryFrom; + | ^^^^^^^^^^^^^^^^^^^^^ + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + | + = note: the item `TryFrom` is already defined here + | +note: the lint level is defined here + --> $DIR/use-redundant-prelude-rust-2021.rs:3:9 + | +LL | #![warn(unused_imports)] + | ^^^^^^^^^^^^^^ + +warning: the item `TryInto` is imported redundantly + --> $DIR/use-redundant-prelude-rust-2021.rs:6:5 + | +LL | use std::convert::TryInto; + | ^^^^^^^^^^^^^^^^^^^^^ + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + | + = note: the item `TryInto` is already defined here + +warning: 2 warnings emitted + diff --git a/tests/ui/rust-2018/remove-extern-crate.fixed b/tests/ui/rust-2018/remove-extern-crate.fixed index f025ccfeaeb..19b1dc6fb01 100644 --- a/tests/ui/rust-2018/remove-extern-crate.fixed +++ b/tests/ui/rust-2018/remove-extern-crate.fixed @@ -6,6 +6,7 @@ #![warn(rust_2018_idioms)] #![allow(dropping_copy_types)] +#![allow(unused_imports)] //~ WARNING unused extern crate // Shouldn't suggest changing to `use`, as `another_name` diff --git a/tests/ui/rust-2018/remove-extern-crate.rs b/tests/ui/rust-2018/remove-extern-crate.rs index 0312964d5f6..88ef858da14 100644 --- a/tests/ui/rust-2018/remove-extern-crate.rs +++ b/tests/ui/rust-2018/remove-extern-crate.rs @@ -6,6 +6,7 @@ #![warn(rust_2018_idioms)] #![allow(dropping_copy_types)] +#![allow(unused_imports)] extern crate core; //~ WARNING unused extern crate // Shouldn't suggest changing to `use`, as `another_name` diff --git a/tests/ui/rust-2018/remove-extern-crate.stderr b/tests/ui/rust-2018/remove-extern-crate.stderr index f752cac8ed6..020db9975c0 100644 --- a/tests/ui/rust-2018/remove-extern-crate.stderr +++ b/tests/ui/rust-2018/remove-extern-crate.stderr @@ -1,5 +1,5 @@ warning: unused extern crate - --> $DIR/remove-extern-crate.rs:10:1 + --> $DIR/remove-extern-crate.rs:11:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ help: remove it @@ -12,7 +12,7 @@ LL | #![warn(rust_2018_idioms)] = note: `#[warn(unused_extern_crates)]` implied by `#[warn(rust_2018_idioms)]` warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:34:5 + --> $DIR/remove-extern-crate.rs:35:5 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | use core; | ~~~ warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:44:5 + --> $DIR/remove-extern-crate.rs:45:5 | LL | pub extern crate core; | ^^^^^^^^^^^^^^^^^^^^^^