@@ -64,7 +64,7 @@ use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
64
64
use syntax:: ast:: { Local , Mutability , Pat , PatKind , Path } ;
65
65
use syntax:: ast:: { PathSegment , PathParameters , QSelf , TraitItemKind , TraitRef , Ty , TyKind } ;
66
66
67
- use syntax_pos:: { Span , DUMMY_SP } ;
67
+ use syntax_pos:: { Span , DUMMY_SP , MultiSpan } ;
68
68
use errors:: DiagnosticBuilder ;
69
69
70
70
use std:: cell:: { Cell , RefCell } ;
@@ -896,6 +896,7 @@ enum NameBindingKind<'a> {
896
896
Ambiguity {
897
897
b1 : & ' a NameBinding < ' a > ,
898
898
b2 : & ' a NameBinding < ' a > ,
899
+ legacy : bool ,
899
900
}
900
901
}
901
902
@@ -907,13 +908,15 @@ struct AmbiguityError<'a> {
907
908
lexical : bool ,
908
909
b1 : & ' a NameBinding < ' a > ,
909
910
b2 : & ' a NameBinding < ' a > ,
911
+ legacy : bool ,
910
912
}
911
913
912
914
impl < ' a > NameBinding < ' a > {
913
915
fn module ( & self ) -> Option < Module < ' a > > {
914
916
match self . kind {
915
917
NameBindingKind :: Module ( module) => Some ( module) ,
916
918
NameBindingKind :: Import { binding, .. } => binding. module ( ) ,
919
+ NameBindingKind :: Ambiguity { legacy : true , b1, .. } => b1. module ( ) ,
917
920
_ => None ,
918
921
}
919
922
}
@@ -923,6 +926,7 @@ impl<'a> NameBinding<'a> {
923
926
NameBindingKind :: Def ( def) => def,
924
927
NameBindingKind :: Module ( module) => module. def ( ) . unwrap ( ) ,
925
928
NameBindingKind :: Import { binding, .. } => binding. def ( ) ,
929
+ NameBindingKind :: Ambiguity { legacy : true , b1, .. } => b1. def ( ) ,
926
930
NameBindingKind :: Ambiguity { .. } => Def :: Err ,
927
931
}
928
932
}
@@ -1349,11 +1353,14 @@ impl<'a> Resolver<'a> {
1349
1353
self . record_use ( name, ns, binding, span)
1350
1354
}
1351
1355
NameBindingKind :: Import { .. } => false ,
1352
- NameBindingKind :: Ambiguity { b1, b2 } => {
1356
+ NameBindingKind :: Ambiguity { b1, b2, legacy } => {
1353
1357
self . ambiguity_errors . push ( AmbiguityError {
1354
- span : span, name : name, lexical : false , b1 : b1, b2 : b2,
1358
+ span : span, name : name, lexical : false , b1 : b1, b2 : b2, legacy : legacy ,
1355
1359
} ) ;
1356
- true
1360
+ if legacy {
1361
+ self . record_use ( name, ns, b1, span) ;
1362
+ }
1363
+ !legacy
1357
1364
}
1358
1365
_ => false
1359
1366
}
@@ -2946,6 +2953,7 @@ impl<'a> Resolver<'a> {
2946
2953
2947
2954
let mut lookup_results = Vec :: new ( ) ;
2948
2955
let mut worklist = Vec :: new ( ) ;
2956
+ let mut seen_modules = FxHashSet ( ) ;
2949
2957
worklist. push ( ( self . graph_root , Vec :: new ( ) , false ) ) ;
2950
2958
2951
2959
while let Some ( ( in_module,
@@ -3001,7 +3009,7 @@ impl<'a> Resolver<'a> {
3001
3009
if !in_module_is_extern || name_binding. vis == ty:: Visibility :: Public {
3002
3010
// add the module to the lookup
3003
3011
let is_extern = in_module_is_extern || name_binding. is_extern_crate ( ) ;
3004
- if !worklist . iter ( ) . any ( | & ( m , .. ) | m . def ( ) == module . def ( ) ) {
3012
+ if seen_modules . insert ( module . def_id ( ) . unwrap ( ) ) {
3005
3013
worklist. push ( ( module, path_segments, is_extern) ) ;
3006
3014
}
3007
3015
}
@@ -3065,26 +3073,39 @@ impl<'a> Resolver<'a> {
3065
3073
self . report_shadowing_errors ( ) ;
3066
3074
let mut reported_spans = FxHashSet ( ) ;
3067
3075
3068
- for & AmbiguityError { span, name, b1, b2, lexical } in & self . ambiguity_errors {
3076
+ for & AmbiguityError { span, name, b1, b2, lexical, legacy } in & self . ambiguity_errors {
3069
3077
if !reported_spans. insert ( span) { continue }
3070
3078
let participle = |binding : & NameBinding | {
3071
3079
if binding. is_import ( ) { "imported" } else { "defined" }
3072
3080
} ;
3073
3081
let msg1 = format ! ( "`{}` could resolve to the name {} here" , name, participle( b1) ) ;
3074
3082
let msg2 = format ! ( "`{}` could also resolve to the name {} here" , name, participle( b2) ) ;
3075
- self . session . struct_span_err ( span, & format ! ( "`{}` is ambiguous" , name) )
3076
- . span_note ( b1. span , & msg1)
3077
- . span_note ( b2. span , & msg2)
3078
- . note ( & if !lexical && b1. is_glob_import ( ) {
3079
- format ! ( "consider adding an explicit import of `{}` to disambiguate" , name)
3080
- } else if let Def :: Macro ( ..) = b1. def ( ) {
3081
- format ! ( "macro-expanded {} do not shadow" ,
3082
- if b1. is_import( ) { "macro imports" } else { "macros" } )
3083
- } else {
3084
- format ! ( "macro-expanded {} do not shadow when used in a macro invocation path" ,
3085
- if b1. is_import( ) { "imports" } else { "items" } )
3086
- } )
3087
- . emit ( ) ;
3083
+ let note = if !lexical && b1. is_glob_import ( ) {
3084
+ format ! ( "consider adding an explicit import of `{}` to disambiguate" , name)
3085
+ } else if let Def :: Macro ( ..) = b1. def ( ) {
3086
+ format ! ( "macro-expanded {} do not shadow" ,
3087
+ if b1. is_import( ) { "macro imports" } else { "macros" } )
3088
+ } else {
3089
+ format ! ( "macro-expanded {} do not shadow when used in a macro invocation path" ,
3090
+ if b1. is_import( ) { "imports" } else { "items" } )
3091
+ } ;
3092
+ if legacy {
3093
+ let id = match b2. kind {
3094
+ NameBindingKind :: Import { directive, .. } => directive. id ,
3095
+ _ => unreachable ! ( ) ,
3096
+ } ;
3097
+ let mut span = MultiSpan :: from_span ( span) ;
3098
+ span. push_span_label ( b1. span , msg1) ;
3099
+ span. push_span_label ( b2. span , msg2) ;
3100
+ let msg = format ! ( "`{}` is ambiguous" , name) ;
3101
+ self . session . add_lint ( lint:: builtin:: LEGACY_IMPORTS , id, span, msg) ;
3102
+ } else {
3103
+ self . session . struct_span_err ( span, & format ! ( "`{}` is ambiguous" , name) )
3104
+ . span_note ( b1. span , & msg1)
3105
+ . span_note ( b2. span , & msg2)
3106
+ . note ( & note)
3107
+ . emit ( ) ;
3108
+ }
3088
3109
}
3089
3110
3090
3111
for & PrivacyError ( span, name, binding) in & self . privacy_errors {
0 commit comments