diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index 74c80a08b12ab..ee1799fad8e15 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -135,7 +135,7 @@ impl ToOwned for T /// Another example showing how to keep `Cow` in a struct: /// /// ``` -/// use std::borrow::{Cow, ToOwned}; +/// use std::borrow::Cow; /// /// struct Items<'a, X: 'a> where [X]: ToOwned> { /// values: Cow<'a, [X]>, diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 753f10e6a0ad0..3b888244341f9 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1421,7 +1421,6 @@ impl fmt::Display for RefMut<'_, T> { /// /// ``` /// use std::cell::UnsafeCell; -/// use std::marker::Sync; /// /// # #[allow(dead_code)] /// struct NotThreadSafe { diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 10a5c1479fa6a..2d8a2c6321fa8 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -483,6 +483,7 @@ pub enum BuiltinLintDiagnostics { UnknownCrateTypes(Span, String, String), UnusedImports(String, Vec<(Span, String)>), NestedImplTrait { outer_impl_trait_span: Span, inner_impl_trait_span: Span }, + RedundantImport(Vec<(Span, bool)>, ast::Ident), } impl BuiltinLintDiagnostics { @@ -579,6 +580,15 @@ impl BuiltinLintDiagnostics { db.span_label(outer_impl_trait_span, "outer `impl Trait`"); db.span_label(inner_impl_trait_span, "nested `impl Trait` here"); } + BuiltinLintDiagnostics::RedundantImport(spans, ident) => { + for (span, is_imported) in spans { + let introduced = if is_imported { "imported" } else { "defined" }; + db.span_label( + span, + format!("the item `{}` is already {} here", ident, introduced) + ); + } + } } } } diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 1b4c36b8b06c3..05d80f9203f14 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -777,7 +777,6 @@ impl<'enc, 'a, 'tcx, E> CacheEncoder<'enc, 'a, 'tcx, E> value: &V) -> Result<(), E::Error> { - use crate::ty::codec::TyEncoder; let start_pos = self.position(); tag.encode(self)?; diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index fc79e868fb4bf..f6956bd5736eb 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -372,7 +372,6 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { // Returns a Value of the "eh_unwind_resume" lang item if one is defined, // otherwise declares it as an external function. fn eh_unwind_resume(&self) -> &'ll Value { - use crate::attributes; let unwresume = &self.eh_unwind_resume; if let Some(llfn) = unwresume.get() { return llfn; diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 7a31c5b3950e0..fc4f6b8324787 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -732,7 +732,6 @@ fn cast_int_to_float<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // All inputs greater or equal to (f32::MAX + 0.5 ULP) are rounded to infinity, // and for everything else LLVM's uitofp works just fine. use rustc_apfloat::ieee::Single; - use rustc_apfloat::Float; const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1) << (Single::MAX_EXP - Single::PRECISION as i16); let max = bx.cx().const_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP); diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index 7fb2cb9d39362..efc18d401c082 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -77,7 +77,6 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> { } fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool { - use syntax_pos::DUMMY_SP; if ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all()) { return false; } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 6b4b437930d26..ebbc5a3d3a340 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -155,7 +155,7 @@ impl CodeSuggestion { /// Returns the assembled code suggestions and whether they should be shown with an underline. pub fn splice_lines(&self, cm: &SourceMapperDyn) -> Vec<(String, Vec)> { - use syntax_pos::{CharPos, Loc, Pos}; + use syntax_pos::{CharPos, Pos}; fn push_trailing(buf: &mut String, line_opt: Option<&Cow<'_, str>>, diff --git a/src/librustc_interface/profile/mod.rs b/src/librustc_interface/profile/mod.rs index d0c8dff207083..2e71d46f4154c 100644 --- a/src/librustc_interface/profile/mod.rs +++ b/src/librustc_interface/profile/mod.rs @@ -62,7 +62,6 @@ fn total_duration(traces: &[trace::Rec]) -> Duration { fn profile_queries_thread(r: Receiver) { use self::trace::*; use std::fs::File; - use std::time::{Instant}; let mut profq_msgs: Vec = vec![]; let mut frame: StackFrame = StackFrame { parse_st: ParseState::Clear, traces: vec![] }; diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 6c532fce57f0e..622cf00ed86e7 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -427,7 +427,6 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { let mut kind = match (lo, hi) { (PatternKind::Constant { value: lo }, PatternKind::Constant { value: hi }) => { - use std::cmp::Ordering; let cmp = compare_const_vals( self.tcx, lo, diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index ca93007788e03..488f81d8f740e 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -331,8 +331,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> val: ImmTy<'tcx, M::PointerTag>, ) -> EvalResult<'tcx, Scalar> { use rustc::mir::UnOp::*; - use rustc_apfloat::ieee::{Single, Double}; - use rustc_apfloat::Float; let layout = val.layout; let val = val.to_scalar()?; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ab3d87fafdac7..3703ea08b6253 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1738,7 +1738,6 @@ impl<'a> Resolver<'a> { /// just that an error occurred. pub fn resolve_str_path_error(&mut self, span: Span, path_str: &str, is_value: bool) -> Result { - use std::iter; let mut errored = false; let path = if path_str.starts_with("::") { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index c2d2bd753c82e..7ea07f5e0cbcb 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -7,6 +7,7 @@ use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyErro use crate::{Resolver, Segment}; use crate::{names_to_string, module_to_string}; use crate::{resolve_error, ResolutionError, Suggestion}; +use crate::ModuleKind; use crate::macros::ParentScope; use errors::Applicability; @@ -14,7 +15,11 @@ use errors::Applicability; use rustc_data_structures::ptr_key::PtrKey; use rustc::ty; use rustc::lint::builtin::BuiltinLintDiagnostics; -use rustc::lint::builtin::{DUPLICATE_MACRO_EXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE}; +use rustc::lint::builtin::{ + DUPLICATE_MACRO_EXPORTS, + PUB_USE_OF_PRIVATE_EXTERN_CRATE, + UNUSED_IMPORTS, +}; use rustc::hir::def_id::{CrateNum, DefId}; use rustc::hir::def::*; use rustc::session::DiagnosticMessageId; @@ -1227,10 +1232,97 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { import[ns] = Some(PathResolution::new(def)); }); + self.check_for_redundant_imports( + ident, + directive, + source_bindings, + target_bindings, + target, + ); + debug!("(resolving single import) successfully resolved import"); None } + fn check_for_redundant_imports( + &mut self, + ident: Ident, + directive: &'b ImportDirective<'b>, + source_bindings: &PerNS, Determinacy>>>, + target_bindings: &PerNS>>>, + target: Ident, + ) { + // Skip if the import was produced by a macro. + if directive.parent_scope.expansion != Mark::root() { + return; + } + + // Skip if we are inside a named module (in contrast to an anonymous + // module defined by a block). + if let ModuleKind::Def(_, _) = directive.parent_scope.module.kind { + return; + } + + let mut is_redundant = PerNS { + value_ns: None, + type_ns: None, + macro_ns: None, + }; + + let mut redundant_span = PerNS { + value_ns: None, + type_ns: None, + macro_ns: None, + }; + + self.per_ns(|this, ns| if let Some(binding) = source_bindings[ns].get().ok() { + if binding.def() == Def::Err { + return; + } + + let orig_blacklisted_binding = mem::replace( + &mut this.blacklisted_binding, + target_bindings[ns].get() + ); + + match this.early_resolve_ident_in_lexical_scope( + target, + ScopeSet::Import(ns), + &directive.parent_scope, + false, + false, + directive.span, + ) { + Ok(other_binding) => { + is_redundant[ns] = Some( + binding.def() == other_binding.def() + && !other_binding.is_ambiguity() + ); + redundant_span[ns] = + Some((other_binding.span, other_binding.is_import())); + } + Err(_) => is_redundant[ns] = Some(false) + } + + this.blacklisted_binding = orig_blacklisted_binding; + }); + + if !is_redundant.is_empty() && + is_redundant.present_items().all(|is_redundant| is_redundant) + { + self.session.buffer_lint_with_diagnostic( + UNUSED_IMPORTS, + directive.id, + directive.span, + &format!("the item `{}` is imported redundantly", ident), + BuiltinLintDiagnostics::RedundantImport( + redundant_span.present_items().collect(), + ident, + ), + ); + } + } + fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) { let module = match directive.imported_module.get().unwrap() { ModuleOrUniformRoot::Module(module) => module, diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 920270b5473cf..3579810b8d75f 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -420,9 +420,6 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>( def_id: DefId, return_ty: Option>, ) { - use ty::subst::Subst; - use rustc::ty::TypeFoldable; - let predicates = fcx.tcx.predicates_of(def_id); let generics = tcx.generics_of(def_id); @@ -1010,8 +1007,6 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>( span: Span, id: hir::HirId) { - use rustc::ty::TypeFoldable; - let empty_env = ty::ParamEnv::empty(); let def_id = fcx.tcx.hir().local_def_id_from_hir_id(id); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 9220d2feed2d2..f7e8cdeaeca89 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1069,8 +1069,6 @@ themePicker.onblur = handleThemeButtonsBlur; } if cx.shared.include_sources { - use std::path::Component; - let mut hierarchy = Hierarchy::new(OsString::new()); for source in cx.shared.local_sources.iter() .filter_map(|p| p.0.strip_prefix(&cx.shared.src_root) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index f1d4d8470b2a5..0bbc7c5c4b223 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -371,8 +371,7 @@ pub fn make_test(s: &str, // Uses libsyntax to parse the doctest and find if there's a main fn and the extern // crate already is included. let (already_has_main, already_has_extern_crate, found_macro) = crate::syntax::with_globals(|| { - use crate::syntax::{ast, parse::{self, ParseSess}, source_map::FilePathMapping}; - use crate::syntax_pos::FileName; + use crate::syntax::{parse::{self, ParseSess}, source_map::FilePathMapping}; use errors::emitter::EmitterWriter; use errors::Handler; diff --git a/src/test/run-pass/binding/match-arm-statics.rs b/src/test/run-pass/binding/match-arm-statics.rs index 359c39211588c..5f7e357eeb2a9 100644 --- a/src/test/run-pass/binding/match-arm-statics.rs +++ b/src/test/run-pass/binding/match-arm-statics.rs @@ -45,8 +45,6 @@ pub mod glfw { } fn issue_6533() { - use glfw; - fn action_to_str(state: glfw::InputState) -> &'static str { use glfw::{RELEASE, PRESS, REPEAT}; match state { diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs index 56222fa46f7c9..8c17b01e2bd89 100644 --- a/src/test/run-pass/ifmt.rs +++ b/src/test/run-pass/ifmt.rs @@ -238,7 +238,6 @@ pub fn main() { // Basic test to make sure that we can invoke the `write!` macro with an // fmt::Write instance. fn test_write() { - use std::fmt::Write; let mut buf = String::new(); write!(&mut buf, "{}", 3); { @@ -267,7 +266,6 @@ fn test_print() { // Just make sure that the macros are defined, there's not really a lot that we // can do with them just yet (to test the output) fn test_format_args() { - use std::fmt::Write; let mut buf = String::new(); { let w = &mut buf; diff --git a/src/test/run-pass/invalid_const_promotion.rs b/src/test/run-pass/invalid_const_promotion.rs index 1524373895d9b..2775aac015615 100644 --- a/src/test/run-pass/invalid_const_promotion.rs +++ b/src/test/run-pass/invalid_const_promotion.rs @@ -25,7 +25,6 @@ fn foo() { #[cfg(unix)] fn check_status(status: std::process::ExitStatus) { - use libc; use std::os::unix::process::ExitStatusExt; assert!(status.signal() == Some(libc::SIGILL) diff --git a/src/test/run-pass/issues/issue-38556.rs b/src/test/run-pass/issues/issue-38556.rs index 0cc247f5b9ca5..63fd9db08ff2f 100644 --- a/src/test/run-pass/issues/issue-38556.rs +++ b/src/test/run-pass/issues/issue-38556.rs @@ -9,6 +9,5 @@ macro_rules! reexport { reexport!(); fn main() { - use Bar; fn f(_: Bar) {} } diff --git a/src/test/run-pass/issues/issue-39367.rs b/src/test/run-pass/issues/issue-39367.rs index bd92224bce161..484cd782a09df 100644 --- a/src/test/run-pass/issues/issue-39367.rs +++ b/src/test/run-pass/issues/issue-39367.rs @@ -15,7 +15,6 @@ fn arena() -> &'static ArenaSet> { fn require_sync(_: &T) { } unsafe fn __stability() -> &'static ArenaSet> { use std::mem::transmute; - use std::boxed::Box; static mut DATA: *const ArenaSet> = 0 as *const ArenaSet>; static mut ONCE: Once = ONCE_INIT; diff --git a/src/test/run-pass/out-of-stack.rs b/src/test/run-pass/out-of-stack.rs index 72d6d6806229e..9f868d6e5c3e4 100644 --- a/src/test/run-pass/out-of-stack.rs +++ b/src/test/run-pass/out-of-stack.rs @@ -36,7 +36,6 @@ fn loud_recurse() { #[cfg(unix)] fn check_status(status: std::process::ExitStatus) { - use libc; use std::os::unix::process::ExitStatusExt; assert!(!status.success()); diff --git a/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/basic.rs b/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/basic.rs index 15449a6b83e2e..566b3581046d9 100644 --- a/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/basic.rs +++ b/src/test/run-pass/rfcs/rfc-2126-extern-absolute-paths/basic.rs @@ -4,6 +4,8 @@ // compile-flags:--extern xcrate // edition:2018 +#![allow(unused_imports)] + use xcrate::Z; fn f() { diff --git a/src/test/run-pass/traits/traits-multidispatch-infer-convert-target.rs b/src/test/run-pass/traits/traits-multidispatch-infer-convert-target.rs index ca47d9736f63c..626e1ae71bc2f 100644 --- a/src/test/run-pass/traits/traits-multidispatch-infer-convert-target.rs +++ b/src/test/run-pass/traits/traits-multidispatch-infer-convert-target.rs @@ -28,7 +28,6 @@ where T : Convert } fn main() { - use std::default::Default; // T = i16, U = u32 test(22_i16, Default::default(), 2, 4); diff --git a/src/test/ui/lint/lint-unused-imports.rs b/src/test/ui/lint/lint-unused-imports.rs index 9c5b206203c1d..4754d8880763a 100644 --- a/src/test/ui/lint/lint-unused-imports.rs +++ b/src/test/ui/lint/lint-unused-imports.rs @@ -66,6 +66,7 @@ mod bar { fn g() { use self::g; //~ ERROR unused import: `self::g` + //~^ ERROR the item `g` is imported redundantly fn f() { self::g(); } @@ -75,6 +76,7 @@ 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/src/test/ui/lint/lint-unused-imports.stderr b/src/test/ui/lint/lint-unused-imports.stderr index f9a54f477f998..96d71a228a5f2 100644 --- a/src/test/ui/lint/lint-unused-imports.stderr +++ b/src/test/ui/lint/lint-unused-imports.stderr @@ -34,14 +34,36 @@ 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:77:9 + --> $DIR/lint-unused-imports.rs:78:9 | LL | use test2::foo; | ^^^^^^^^^^ @@ -52,5 +74,5 @@ error: unused import: `test::B2` LL | use test::B2; | ^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 10 previous errors diff --git a/src/test/ui/lint/use-redundant.rs b/src/test/ui/lint/use-redundant.rs new file mode 100644 index 0000000000000..328f8232bafa8 --- /dev/null +++ b/src/test/ui/lint/use-redundant.rs @@ -0,0 +1,27 @@ +// compile-pass +#![warn(unused_imports)] + +use crate::foo::Bar; //~ WARNING first import + +mod foo { + pub type Bar = i32; +} + +fn baz() -> Bar { + 3 +} + +mod m1 { pub struct S {} } +mod m2 { pub struct S {} } + +use m1::*; +use m2::*; + +fn main() { + use crate::foo::Bar; //~ WARNING redundant import + let _a: Bar = 3; + baz(); + + use m1::S; //~ WARNING redundant import + let _s = S {}; +} diff --git a/src/test/ui/lint/use-redundant.stderr b/src/test/ui/lint/use-redundant.stderr new file mode 100644 index 0000000000000..fbd9f81f18f8a --- /dev/null +++ b/src/test/ui/lint/use-redundant.stderr @@ -0,0 +1,27 @@ +warning: unused import: `m1::*` + --> $DIR/use-redundant.rs:17:5 + | +LL | use m1::*; + | ^^^^^ + | +note: lint level defined here + --> $DIR/use-redundant.rs:2:9 + | +LL | #![warn(unused_imports)] + | ^^^^^^^^^^^^^^ + +warning: unused import: `m2::*` + --> $DIR/use-redundant.rs:18:5 + | +LL | use m2::*; + | ^^^^^ + +warning: the item `Bar` is imported redundantly + --> $DIR/use-redundant.rs:21:9 + | +LL | use crate::foo::Bar; + | --------------- the item `Bar` is already imported here +... +LL | use crate::foo::Bar; + | ^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/rust-2018/future-proofing-locals.rs b/src/test/ui/rust-2018/future-proofing-locals.rs index 1e53c2d1daca4..2c388cf3713b0 100644 --- a/src/test/ui/rust-2018/future-proofing-locals.rs +++ b/src/test/ui/rust-2018/future-proofing-locals.rs @@ -1,6 +1,7 @@ // edition:2018 #![allow(non_camel_case_types)] +#![allow(unused_imports)] mod T { pub struct U; diff --git a/src/test/ui/rust-2018/future-proofing-locals.stderr b/src/test/ui/rust-2018/future-proofing-locals.stderr index 4d666d22afed1..7021489a6ddcf 100644 --- a/src/test/ui/rust-2018/future-proofing-locals.stderr +++ b/src/test/ui/rust-2018/future-proofing-locals.stderr @@ -1,53 +1,53 @@ error: imports cannot refer to type parameters - --> $DIR/future-proofing-locals.rs:13:9 + --> $DIR/future-proofing-locals.rs:14:9 | LL | use T as _; | ^ error: imports cannot refer to type parameters - --> $DIR/future-proofing-locals.rs:14:9 + --> $DIR/future-proofing-locals.rs:15:9 | LL | use T::U; | ^ error: imports cannot refer to type parameters - --> $DIR/future-proofing-locals.rs:15:9 + --> $DIR/future-proofing-locals.rs:16:9 | LL | use T::*; | ^ error: imports cannot refer to type parameters - --> $DIR/future-proofing-locals.rs:19:9 + --> $DIR/future-proofing-locals.rs:20:9 | LL | use T; | ^ error: imports cannot refer to local variables - --> $DIR/future-proofing-locals.rs:25:9 + --> $DIR/future-proofing-locals.rs:26:9 | LL | use x as _; | ^ error: imports cannot refer to local variables - --> $DIR/future-proofing-locals.rs:31:9 + --> $DIR/future-proofing-locals.rs:32:9 | LL | use x; | ^ error: imports cannot refer to local variables - --> $DIR/future-proofing-locals.rs:37:17 + --> $DIR/future-proofing-locals.rs:38:17 | LL | use x; | ^ error: imports cannot refer to type parameters - --> $DIR/future-proofing-locals.rs:45:10 + --> $DIR/future-proofing-locals.rs:46:10 | LL | use {T as _, x}; | ^ error: imports cannot refer to local variables - --> $DIR/future-proofing-locals.rs:45:18 + --> $DIR/future-proofing-locals.rs:46:18 | LL | use {T as _, x}; | ^