@@ -7,14 +7,19 @@ use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyErro
7
7
use crate :: { Resolver , Segment } ;
8
8
use crate :: { names_to_string, module_to_string} ;
9
9
use crate :: { resolve_error, ResolutionError , Suggestion } ;
10
+ use crate :: ModuleKind ;
10
11
use crate :: macros:: ParentScope ;
11
12
12
13
use errors:: Applicability ;
13
14
14
15
use rustc_data_structures:: ptr_key:: PtrKey ;
15
16
use rustc:: ty;
16
17
use rustc:: lint:: builtin:: BuiltinLintDiagnostics ;
17
- use rustc:: lint:: builtin:: { DUPLICATE_MACRO_EXPORTS , PUB_USE_OF_PRIVATE_EXTERN_CRATE } ;
18
+ use rustc:: lint:: builtin:: {
19
+ DUPLICATE_MACRO_EXPORTS ,
20
+ PUB_USE_OF_PRIVATE_EXTERN_CRATE ,
21
+ UNUSED_IMPORTS ,
22
+ } ;
18
23
use rustc:: hir:: def_id:: { CrateNum , DefId } ;
19
24
use rustc:: hir:: def:: * ;
20
25
use rustc:: session:: DiagnosticMessageId ;
@@ -1227,10 +1232,97 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
1227
1232
import[ ns] = Some ( PathResolution :: new ( def) ) ;
1228
1233
} ) ;
1229
1234
1235
+ self . check_for_redundant_imports (
1236
+ ident,
1237
+ directive,
1238
+ source_bindings,
1239
+ target_bindings,
1240
+ target,
1241
+ ) ;
1242
+
1230
1243
debug ! ( "(resolving single import) successfully resolved import" ) ;
1231
1244
None
1232
1245
}
1233
1246
1247
+ fn check_for_redundant_imports (
1248
+ & mut self ,
1249
+ ident : Ident ,
1250
+ directive : & ' b ImportDirective < ' b > ,
1251
+ source_bindings : & PerNS < Cell < Result < & ' b NameBinding < ' b > , Determinacy > > > ,
1252
+ target_bindings : & PerNS < Cell < Option < & ' b NameBinding < ' b > > > > ,
1253
+ target : Ident ,
1254
+ ) {
1255
+ // Skip if the import was produced by a macro.
1256
+ if directive. parent_scope . expansion != Mark :: root ( ) {
1257
+ return ;
1258
+ }
1259
+
1260
+ // Skip if we are inside a named module (in contrast to an anonymous
1261
+ // module defined by a block).
1262
+ if let ModuleKind :: Def ( _, _) = directive. parent_scope . module . kind {
1263
+ return ;
1264
+ }
1265
+
1266
+ let mut is_redundant = PerNS {
1267
+ value_ns : None ,
1268
+ type_ns : None ,
1269
+ macro_ns : None ,
1270
+ } ;
1271
+
1272
+ let mut redundant_span = PerNS {
1273
+ value_ns : None ,
1274
+ type_ns : None ,
1275
+ macro_ns : None ,
1276
+ } ;
1277
+
1278
+ self . per_ns ( |this, ns| if let Some ( binding) = source_bindings[ ns] . get ( ) . ok ( ) {
1279
+ if binding. def ( ) == Def :: Err {
1280
+ return ;
1281
+ }
1282
+
1283
+ let orig_blacklisted_binding = mem:: replace (
1284
+ & mut this. blacklisted_binding ,
1285
+ target_bindings[ ns] . get ( )
1286
+ ) ;
1287
+
1288
+ match this. early_resolve_ident_in_lexical_scope (
1289
+ target,
1290
+ ScopeSet :: Import ( ns) ,
1291
+ & directive. parent_scope ,
1292
+ false ,
1293
+ false ,
1294
+ directive. span ,
1295
+ ) {
1296
+ Ok ( other_binding) => {
1297
+ is_redundant[ ns] = Some (
1298
+ binding. def ( ) == other_binding. def ( )
1299
+ && !other_binding. is_ambiguity ( )
1300
+ ) ;
1301
+ redundant_span[ ns] =
1302
+ Some ( ( other_binding. span , other_binding. is_import ( ) ) ) ;
1303
+ }
1304
+ Err ( _) => is_redundant[ ns] = Some ( false )
1305
+ }
1306
+
1307
+ this. blacklisted_binding = orig_blacklisted_binding;
1308
+ } ) ;
1309
+
1310
+ if !is_redundant. is_empty ( ) &&
1311
+ is_redundant. present_items ( ) . all ( |is_redundant| is_redundant)
1312
+ {
1313
+ self . session . buffer_lint_with_diagnostic (
1314
+ UNUSED_IMPORTS ,
1315
+ directive. id ,
1316
+ directive. span ,
1317
+ & format ! ( "the item `{}` is imported redundantly" , ident) ,
1318
+ BuiltinLintDiagnostics :: RedundantImport (
1319
+ redundant_span. present_items ( ) . collect ( ) ,
1320
+ ident,
1321
+ ) ,
1322
+ ) ;
1323
+ }
1324
+ }
1325
+
1234
1326
fn resolve_glob_import ( & mut self , directive : & ' b ImportDirective < ' b > ) {
1235
1327
let module = match directive. imported_module . get ( ) . unwrap ( ) {
1236
1328
ModuleOrUniformRoot :: Module ( module) => module,
0 commit comments