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