@@ -2222,7 +2222,7 @@ impl<'a> Resolver<'a> {
22222222 segments : use_tree. prefix . make_root ( ) . into_iter ( ) . collect ( ) ,
22232223 span : use_tree. span ,
22242224 } ;
2225- self . resolve_use_tree ( item. id , use_tree, & path) ;
2225+ self . resolve_use_tree ( item. id , use_tree. span , item . id , use_tree , & path) ;
22262226 }
22272227
22282228 ItemKind :: ExternCrate ( _) | ItemKind :: MacroDef ( ..) | ItemKind :: GlobalAsm ( _) => {
@@ -2233,7 +2233,18 @@ impl<'a> Resolver<'a> {
22332233 }
22342234 }
22352235
2236- fn resolve_use_tree ( & mut self , id : NodeId , use_tree : & ast:: UseTree , prefix : & Path ) {
2236+ /// For the most part, use trees are desugared into `ImportDirective` instances
2237+ /// when building the reduced graph (see `build_reduced_graph_for_use_tree`). But
2238+ /// there is one special case we handle here: an empty nested import like
2239+ /// `a::{b::{}}`, which desugares into...no import directives.
2240+ fn resolve_use_tree (
2241+ & mut self ,
2242+ root_id : NodeId ,
2243+ root_span : Span ,
2244+ id : NodeId ,
2245+ use_tree : & ast:: UseTree ,
2246+ prefix : & Path ,
2247+ ) {
22372248 match use_tree. kind {
22382249 ast:: UseTreeKind :: Nested ( ref items) => {
22392250 let path = Path {
@@ -2247,10 +2258,16 @@ impl<'a> Resolver<'a> {
22472258
22482259 if items. len ( ) == 0 {
22492260 // Resolve prefix of an import with empty braces (issue #28388).
2250- self . smart_resolve_path ( id, None , & path, PathSource :: ImportPrefix ) ;
2261+ self . smart_resolve_path_with_crate_lint (
2262+ id,
2263+ None ,
2264+ & path,
2265+ PathSource :: ImportPrefix ,
2266+ CrateLint :: UsePath { root_id, root_span } ,
2267+ ) ;
22512268 } else {
22522269 for & ( ref tree, nested_id) in items {
2253- self . resolve_use_tree ( nested_id, tree, & path) ;
2270+ self . resolve_use_tree ( root_id , root_span , nested_id, tree, & path) ;
22542271 }
22552272 }
22562273 }
@@ -2354,7 +2371,8 @@ impl<'a> Resolver<'a> {
23542371 None ,
23552372 & path,
23562373 trait_ref. path . span ,
2357- PathSource :: Trait ( AliasPossibility :: No )
2374+ PathSource :: Trait ( AliasPossibility :: No ) ,
2375+ CrateLint :: SimplePath ( trait_ref. ref_id ) ,
23582376 ) . base_def ( ) ;
23592377 if def != Def :: Err {
23602378 new_id = Some ( def. def_id ( ) ) ;
@@ -2787,18 +2805,38 @@ impl<'a> Resolver<'a> {
27872805 path : & Path ,
27882806 source : PathSource )
27892807 -> PathResolution {
2808+ self . smart_resolve_path_with_crate_lint ( id, qself, path, source, CrateLint :: SimplePath ( id) )
2809+ }
2810+
2811+ /// A variant of `smart_resolve_path` where you also specify extra
2812+ /// information about where the path came from; this extra info is
2813+ /// sometimes needed for the lint that recommends rewriting
2814+ /// absoluate paths to `crate`, so that it knows how to frame the
2815+ /// suggestion. If you are just resolving a path like `foo::bar`
2816+ /// that appears...somewhere, though, then you just want
2817+ /// `CrateLint::SimplePath`, which is what `smart_resolve_path`
2818+ /// already provides.
2819+ fn smart_resolve_path_with_crate_lint (
2820+ & mut self ,
2821+ id : NodeId ,
2822+ qself : Option < & QSelf > ,
2823+ path : & Path ,
2824+ source : PathSource ,
2825+ crate_lint : CrateLint
2826+ ) -> PathResolution {
27902827 let segments = & path. segments . iter ( )
27912828 . map ( |seg| seg. ident )
27922829 . collect :: < Vec < _ > > ( ) ;
2793- self . smart_resolve_path_fragment ( id, qself, segments, path. span , source)
2830+ self . smart_resolve_path_fragment ( id, qself, segments, path. span , source, crate_lint )
27942831 }
27952832
27962833 fn smart_resolve_path_fragment ( & mut self ,
27972834 id : NodeId ,
27982835 qself : Option < & QSelf > ,
27992836 path : & [ Ident ] ,
28002837 span : Span ,
2801- source : PathSource )
2838+ source : PathSource ,
2839+ crate_lint : CrateLint )
28022840 -> PathResolution {
28032841 let ident_span = path. last ( ) . map_or ( span, |ident| ident. span ) ;
28042842 let ns = source. namespace ( ) ;
@@ -2999,9 +3037,16 @@ impl<'a> Resolver<'a> {
29993037 err_path_resolution ( )
30003038 } ;
30013039
3002- let resolution = match self . resolve_qpath_anywhere ( id, qself, path, ns, span,
3003- source. defer_to_typeck ( ) ,
3004- source. global_by_default ( ) ) {
3040+ let resolution = match self . resolve_qpath_anywhere (
3041+ id,
3042+ qself,
3043+ path,
3044+ ns,
3045+ span,
3046+ source. defer_to_typeck ( ) ,
3047+ source. global_by_default ( ) ,
3048+ crate_lint,
3049+ ) {
30053050 Some ( resolution) if resolution. unresolved_segments ( ) == 0 => {
30063051 if is_expected ( resolution. base_def ( ) ) || resolution. base_def ( ) == Def :: Err {
30073052 resolution
@@ -3102,14 +3147,15 @@ impl<'a> Resolver<'a> {
31023147 primary_ns : Namespace ,
31033148 span : Span ,
31043149 defer_to_typeck : bool ,
3105- global_by_default : bool )
3150+ global_by_default : bool ,
3151+ crate_lint : CrateLint )
31063152 -> Option < PathResolution > {
31073153 let mut fin_res = None ;
31083154 // FIXME: can't resolve paths in macro namespace yet, macros are
31093155 // processed by the little special hack below.
31103156 for ( i, ns) in [ primary_ns, TypeNS , ValueNS , /*MacroNS*/ ] . iter ( ) . cloned ( ) . enumerate ( ) {
31113157 if i == 0 || ns != primary_ns {
3112- match self . resolve_qpath ( id, qself, path, ns, span, global_by_default) {
3158+ match self . resolve_qpath ( id, qself, path, ns, span, global_by_default, crate_lint ) {
31133159 // If defer_to_typeck, then resolution > no resolution,
31143160 // otherwise full resolution > partial resolution > no resolution.
31153161 Some ( res) if res. unresolved_segments ( ) == 0 || defer_to_typeck =>
@@ -3137,19 +3183,60 @@ impl<'a> Resolver<'a> {
31373183 path : & [ Ident ] ,
31383184 ns : Namespace ,
31393185 span : Span ,
3140- global_by_default : bool )
3186+ global_by_default : bool ,
3187+ crate_lint : CrateLint )
31413188 -> Option < PathResolution > {
3189+ debug ! (
3190+ "resolve_qpath(id={:?}, qself={:?}, path={:?}, \
3191+ ns={:?}, span={:?}, global_by_default={:?})",
3192+ id,
3193+ qself,
3194+ path,
3195+ ns,
3196+ span,
3197+ global_by_default,
3198+ ) ;
3199+
31423200 if let Some ( qself) = qself {
31433201 if qself. position == 0 {
3144- // FIXME: Create some fake resolution that can't possibly be a type.
3202+ // This is a case like `<T>::B`, where there is no
3203+ // trait to resolve. In that case, we leave the `B`
3204+ // segment to be resolved by type-check.
31453205 return Some ( PathResolution :: with_unresolved_segments (
31463206 Def :: Mod ( DefId :: local ( CRATE_DEF_INDEX ) ) , path. len ( )
31473207 ) ) ;
31483208 }
3149- // Make sure `A::B` in `<T as A>::B::C` is a trait item.
3209+
3210+ // Make sure `A::B` in `<T as A::B>::C` is a trait item.
3211+ //
3212+ // Currently, `path` names the full item (`A::B::C`, in
3213+ // our example). so we extract the prefix of that that is
3214+ // the trait (the slice upto and including
3215+ // `qself.position`). And then we recursively resolve that,
3216+ // but with `qself` set to `None`.
3217+ //
3218+ // However, setting `qself` to none (but not changing the
3219+ // span) loses the information about where this path
3220+ // *actually* appears, so for the purposes of the crate
3221+ // lint we pass along information that this is the trait
3222+ // name from a fully qualified path, and this also
3223+ // contains the full span (the `CrateLint::QPathTrait`).
31503224 let ns = if qself. position + 1 == path. len ( ) { ns } else { TypeNS } ;
3151- let res = self . smart_resolve_path_fragment ( id, None , & path[ ..qself. position + 1 ] ,
3152- span, PathSource :: TraitItem ( ns) ) ;
3225+ let res = self . smart_resolve_path_fragment (
3226+ id,
3227+ None ,
3228+ & path[ ..qself. position + 1 ] ,
3229+ span,
3230+ PathSource :: TraitItem ( ns) ,
3231+ CrateLint :: QPathTrait {
3232+ qpath_id : id,
3233+ qpath_span : qself. path_span ,
3234+ } ,
3235+ ) ;
3236+
3237+ // The remaining segments (the `C` in our example) will
3238+ // have to be resolved by type-check, since that requires doing
3239+ // trait resolution.
31533240 return Some ( PathResolution :: with_unresolved_segments (
31543241 res. base_def ( ) , res. unresolved_segments ( ) + path. len ( ) - qself. position - 1
31553242 ) ) ;
@@ -3160,7 +3247,7 @@ impl<'a> Resolver<'a> {
31603247 Some ( ns) ,
31613248 true ,
31623249 span,
3163- CrateLint :: SimplePath ( id ) ,
3250+ crate_lint ,
31643251 ) {
31653252 PathResult :: NonModule ( path_res) => path_res,
31663253 PathResult :: Module ( module) if !module. is_normal ( ) => {
@@ -3231,6 +3318,16 @@ impl<'a> Resolver<'a> {
32313318 let mut allow_super = true ;
32323319 let mut second_binding = None ;
32333320
3321+ debug ! (
3322+ "resolve_path(path={:?}, opt_ns={:?}, record_used={:?}, \
3323+ path_span={:?}, crate_lint={:?})",
3324+ path,
3325+ opt_ns,
3326+ record_used,
3327+ path_span,
3328+ crate_lint,
3329+ ) ;
3330+
32343331 for ( i, & ident) in path. iter ( ) . enumerate ( ) {
32353332 debug ! ( "resolve_path ident {} {:?}" , i, ident) ;
32363333 let is_last = i == path. len ( ) - 1 ;
@@ -3406,6 +3503,7 @@ impl<'a> Resolver<'a> {
34063503 CrateLint :: No => return ,
34073504 CrateLint :: SimplePath ( id) => ( id, path_span) ,
34083505 CrateLint :: UsePath { root_id, root_span } => ( root_id, root_span) ,
3506+ CrateLint :: QPathTrait { qpath_id, qpath_span } => ( qpath_id, qpath_span) ,
34093507 } ;
34103508
34113509 let first_name = match path. get ( 0 ) {
@@ -4093,8 +4191,14 @@ impl<'a> Resolver<'a> {
40934191 let segments = path. make_root ( ) . iter ( ) . chain ( path. segments . iter ( ) )
40944192 . map ( |seg| seg. ident )
40954193 . collect :: < Vec < _ > > ( ) ;
4096- let def = self . smart_resolve_path_fragment ( id, None , & segments, path. span ,
4097- PathSource :: Visibility ) . base_def ( ) ;
4194+ let def = self . smart_resolve_path_fragment (
4195+ id,
4196+ None ,
4197+ & segments,
4198+ path. span ,
4199+ PathSource :: Visibility ,
4200+ CrateLint :: SimplePath ( id) ,
4201+ ) . base_def ( ) ;
40984202 if def == Def :: Err {
40994203 ty:: Visibility :: Public
41004204 } else {
@@ -4454,6 +4558,7 @@ pub enum MakeGlobMap {
44544558 No ,
44554559}
44564560
4561+ #[ derive( Copy , Clone , Debug ) ]
44574562enum CrateLint {
44584563 /// Do not issue the lint
44594564 No ,
@@ -4467,6 +4572,11 @@ enum CrateLint {
44674572 /// have nested things like `use a::{b, c}`, we care about the
44684573 /// `use a` part.
44694574 UsePath { root_id : NodeId , root_span : Span } ,
4575+
4576+ /// This is the "trait item" from a fully qualified path. For example,
4577+ /// we might be resolving `X::Y::Z` from a path like `<T as X::Y>::Z`.
4578+ /// The `path_span` is the span of the to the trait itself (`X::Y`).
4579+ QPathTrait { qpath_id : NodeId , qpath_span : Span } ,
44704580}
44714581
44724582__build_diagnostic_array ! { librustc_resolve, DIAGNOSTICS }
0 commit comments