@@ -2222,7 +2222,7 @@ impl<'a> Resolver<'a> {
2222
2222
segments : use_tree. prefix . make_root ( ) . into_iter ( ) . collect ( ) ,
2223
2223
span : use_tree. span ,
2224
2224
} ;
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) ;
2226
2226
}
2227
2227
2228
2228
ItemKind :: ExternCrate ( _) | ItemKind :: MacroDef ( ..) | ItemKind :: GlobalAsm ( _) => {
@@ -2233,7 +2233,18 @@ impl<'a> Resolver<'a> {
2233
2233
}
2234
2234
}
2235
2235
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
+ ) {
2237
2248
match use_tree. kind {
2238
2249
ast:: UseTreeKind :: Nested ( ref items) => {
2239
2250
let path = Path {
@@ -2247,10 +2258,16 @@ impl<'a> Resolver<'a> {
2247
2258
2248
2259
if items. len ( ) == 0 {
2249
2260
// 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
+ ) ;
2251
2268
} else {
2252
2269
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) ;
2254
2271
}
2255
2272
}
2256
2273
}
@@ -2354,7 +2371,8 @@ impl<'a> Resolver<'a> {
2354
2371
None ,
2355
2372
& path,
2356
2373
trait_ref. path . span ,
2357
- PathSource :: Trait ( AliasPossibility :: No )
2374
+ PathSource :: Trait ( AliasPossibility :: No ) ,
2375
+ CrateLint :: SimplePath ( trait_ref. ref_id ) ,
2358
2376
) . base_def ( ) ;
2359
2377
if def != Def :: Err {
2360
2378
new_id = Some ( def. def_id ( ) ) ;
@@ -2787,18 +2805,38 @@ impl<'a> Resolver<'a> {
2787
2805
path : & Path ,
2788
2806
source : PathSource )
2789
2807
-> 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 {
2790
2827
let segments = & path. segments . iter ( )
2791
2828
. map ( |seg| seg. ident )
2792
2829
. 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 )
2794
2831
}
2795
2832
2796
2833
fn smart_resolve_path_fragment ( & mut self ,
2797
2834
id : NodeId ,
2798
2835
qself : Option < & QSelf > ,
2799
2836
path : & [ Ident ] ,
2800
2837
span : Span ,
2801
- source : PathSource )
2838
+ source : PathSource ,
2839
+ crate_lint : CrateLint )
2802
2840
-> PathResolution {
2803
2841
let ident_span = path. last ( ) . map_or ( span, |ident| ident. span ) ;
2804
2842
let ns = source. namespace ( ) ;
@@ -2999,9 +3037,16 @@ impl<'a> Resolver<'a> {
2999
3037
err_path_resolution ( )
3000
3038
} ;
3001
3039
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
+ ) {
3005
3050
Some ( resolution) if resolution. unresolved_segments ( ) == 0 => {
3006
3051
if is_expected ( resolution. base_def ( ) ) || resolution. base_def ( ) == Def :: Err {
3007
3052
resolution
@@ -3102,14 +3147,15 @@ impl<'a> Resolver<'a> {
3102
3147
primary_ns : Namespace ,
3103
3148
span : Span ,
3104
3149
defer_to_typeck : bool ,
3105
- global_by_default : bool )
3150
+ global_by_default : bool ,
3151
+ crate_lint : CrateLint )
3106
3152
-> Option < PathResolution > {
3107
3153
let mut fin_res = None ;
3108
3154
// FIXME: can't resolve paths in macro namespace yet, macros are
3109
3155
// processed by the little special hack below.
3110
3156
for ( i, ns) in [ primary_ns, TypeNS , ValueNS , /*MacroNS*/ ] . iter ( ) . cloned ( ) . enumerate ( ) {
3111
3157
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 ) {
3113
3159
// If defer_to_typeck, then resolution > no resolution,
3114
3160
// otherwise full resolution > partial resolution > no resolution.
3115
3161
Some ( res) if res. unresolved_segments ( ) == 0 || defer_to_typeck =>
@@ -3137,19 +3183,60 @@ impl<'a> Resolver<'a> {
3137
3183
path : & [ Ident ] ,
3138
3184
ns : Namespace ,
3139
3185
span : Span ,
3140
- global_by_default : bool )
3186
+ global_by_default : bool ,
3187
+ crate_lint : CrateLint )
3141
3188
-> 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
+
3142
3200
if let Some ( qself) = qself {
3143
3201
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.
3145
3205
return Some ( PathResolution :: with_unresolved_segments (
3146
3206
Def :: Mod ( DefId :: local ( CRATE_DEF_INDEX ) ) , path. len ( )
3147
3207
) ) ;
3148
3208
}
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`).
3150
3224
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.
3153
3240
return Some ( PathResolution :: with_unresolved_segments (
3154
3241
res. base_def ( ) , res. unresolved_segments ( ) + path. len ( ) - qself. position - 1
3155
3242
) ) ;
@@ -3160,7 +3247,7 @@ impl<'a> Resolver<'a> {
3160
3247
Some ( ns) ,
3161
3248
true ,
3162
3249
span,
3163
- CrateLint :: SimplePath ( id ) ,
3250
+ crate_lint ,
3164
3251
) {
3165
3252
PathResult :: NonModule ( path_res) => path_res,
3166
3253
PathResult :: Module ( module) if !module. is_normal ( ) => {
@@ -3231,6 +3318,16 @@ impl<'a> Resolver<'a> {
3231
3318
let mut allow_super = true ;
3232
3319
let mut second_binding = None ;
3233
3320
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
+
3234
3331
for ( i, & ident) in path. iter ( ) . enumerate ( ) {
3235
3332
debug ! ( "resolve_path ident {} {:?}" , i, ident) ;
3236
3333
let is_last = i == path. len ( ) - 1 ;
@@ -3406,6 +3503,7 @@ impl<'a> Resolver<'a> {
3406
3503
CrateLint :: No => return ,
3407
3504
CrateLint :: SimplePath ( id) => ( id, path_span) ,
3408
3505
CrateLint :: UsePath { root_id, root_span } => ( root_id, root_span) ,
3506
+ CrateLint :: QPathTrait { qpath_id, qpath_span } => ( qpath_id, qpath_span) ,
3409
3507
} ;
3410
3508
3411
3509
let first_name = match path. get ( 0 ) {
@@ -4093,8 +4191,14 @@ impl<'a> Resolver<'a> {
4093
4191
let segments = path. make_root ( ) . iter ( ) . chain ( path. segments . iter ( ) )
4094
4192
. map ( |seg| seg. ident )
4095
4193
. 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 ( ) ;
4098
4202
if def == Def :: Err {
4099
4203
ty:: Visibility :: Public
4100
4204
} else {
@@ -4454,6 +4558,7 @@ pub enum MakeGlobMap {
4454
4558
No ,
4455
4559
}
4456
4560
4561
+ #[ derive( Copy , Clone , Debug ) ]
4457
4562
enum CrateLint {
4458
4563
/// Do not issue the lint
4459
4564
No ,
@@ -4467,6 +4572,11 @@ enum CrateLint {
4467
4572
/// have nested things like `use a::{b, c}`, we care about the
4468
4573
/// `use a` part.
4469
4574
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 } ,
4470
4580
}
4471
4581
4472
4582
__build_diagnostic_array ! { librustc_resolve, DIAGNOSTICS }
0 commit comments