@@ -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
+ REDUNDANT_IMPORT ,
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,96 @@ 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
+ // Check if we are at the root of a macro expansion and skip if we are.
1256
+ if directive. parent_scope . expansion != Mark :: root ( ) {
1257
+ return ;
1258
+ }
1259
+
1260
+ if let ModuleKind :: Def ( _, _) = directive. parent_scope . module . kind {
1261
+ return ;
1262
+ }
1263
+
1264
+ let mut is_redundant = PerNS {
1265
+ value_ns : None ,
1266
+ type_ns : None ,
1267
+ macro_ns : None ,
1268
+ } ;
1269
+
1270
+ let mut redundant_span = PerNS {
1271
+ value_ns : None ,
1272
+ type_ns : None ,
1273
+ macro_ns : None ,
1274
+ } ;
1275
+
1276
+ self . per_ns ( |this, ns| if let Some ( binding) = source_bindings[ ns] . get ( ) . ok ( ) {
1277
+ if binding. def ( ) == Def :: Err {
1278
+ return ;
1279
+ }
1280
+
1281
+ let orig_blacklisted_binding = mem:: replace (
1282
+ & mut this. blacklisted_binding ,
1283
+ target_bindings[ ns] . get ( )
1284
+ ) ;
1285
+
1286
+ match this. early_resolve_ident_in_lexical_scope (
1287
+ target,
1288
+ ScopeSet :: Import ( ns) ,
1289
+ & directive. parent_scope ,
1290
+ false ,
1291
+ false ,
1292
+ directive. span ,
1293
+ ) {
1294
+ Ok ( other_binding) => {
1295
+ is_redundant[ ns] = Some ( binding. def ( ) == other_binding. def ( ) ) ;
1296
+ redundant_span[ ns] = Some ( other_binding. span ) ;
1297
+ }
1298
+ Err ( _) => is_redundant[ ns] = Some ( false )
1299
+ }
1300
+
1301
+ this. blacklisted_binding = orig_blacklisted_binding;
1302
+ } ) ;
1303
+
1304
+ if !is_redundant. is_empty ( ) &&
1305
+ is_redundant. present_items ( ) . all ( |is_redundant| is_redundant)
1306
+ {
1307
+ self . session . buffer_lint (
1308
+ REDUNDANT_IMPORT ,
1309
+ directive. id ,
1310
+ directive. span ,
1311
+ & format ! ( "the item `{}` is imported redundantly" , ident) ,
1312
+ ) ;
1313
+
1314
+ for span in redundant_span. present_items ( ) {
1315
+ self . session . buffer_lint (
1316
+ REDUNDANT_IMPORT ,
1317
+ directive. id ,
1318
+ span,
1319
+ "another import"
1320
+ ) ;
1321
+ }
1322
+ }
1323
+ }
1324
+
1234
1325
fn resolve_glob_import ( & mut self , directive : & ' b ImportDirective < ' b > ) {
1235
1326
let module = match directive. imported_module . get ( ) . unwrap ( ) {
1236
1327
ModuleOrUniformRoot :: Module ( module) => module,
0 commit comments