@@ -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 {
@@ -2252,11 +2263,11 @@ impl<'a> Resolver<'a> {
2252
2263
None ,
2253
2264
& path,
2254
2265
PathSource :: ImportPrefix ,
2255
- CrateLint :: SimplePath ( id ) , // TODO seems wrong
2266
+ CrateLint :: UsePath { root_id , root_span } ,
2256
2267
) ;
2257
2268
} else {
2258
2269
for & ( ref tree, nested_id) in items {
2259
- self . resolve_use_tree ( nested_id, tree, & path) ;
2270
+ self . resolve_use_tree ( root_id , root_span , nested_id, tree, & path) ;
2260
2271
}
2261
2272
}
2262
2273
}
@@ -3188,21 +3199,44 @@ impl<'a> Resolver<'a> {
3188
3199
3189
3200
if let Some ( qself) = qself {
3190
3201
if qself. position == 0 {
3191
- // 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.
3192
3205
return Some ( PathResolution :: with_unresolved_segments (
3193
3206
Def :: Mod ( DefId :: local ( CRATE_DEF_INDEX ) ) , path. len ( )
3194
3207
) ) ;
3195
3208
}
3196
- // 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`).
3197
3224
let ns = if qself. position + 1 == path. len ( ) { ns } else { TypeNS } ;
3198
3225
let res = self . smart_resolve_path_fragment (
3199
3226
id,
3200
3227
None ,
3201
3228
& path[ ..qself. position + 1 ] ,
3202
3229
span,
3203
3230
PathSource :: TraitItem ( ns) ,
3204
- crate_lint, // TODO wrong
3231
+ CrateLint :: QPathTrait {
3232
+ qpath_id : id,
3233
+ qpath_span : qself. path_span ,
3234
+ } ,
3205
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.
3206
3240
return Some ( PathResolution :: with_unresolved_segments (
3207
3241
res. base_def ( ) , res. unresolved_segments ( ) + path. len ( ) - qself. position - 1
3208
3242
) ) ;
@@ -3213,7 +3247,7 @@ impl<'a> Resolver<'a> {
3213
3247
Some ( ns) ,
3214
3248
true ,
3215
3249
span,
3216
- CrateLint :: SimplePath ( id ) ,
3250
+ crate_lint ,
3217
3251
) {
3218
3252
PathResult :: NonModule ( path_res) => path_res,
3219
3253
PathResult :: Module ( module) if !module. is_normal ( ) => {
@@ -3468,6 +3502,7 @@ impl<'a> Resolver<'a> {
3468
3502
CrateLint :: No => return ,
3469
3503
CrateLint :: SimplePath ( id) => ( id, path_span) ,
3470
3504
CrateLint :: UsePath { root_id, root_span } => ( root_id, root_span) ,
3505
+ CrateLint :: QPathTrait { qpath_id, qpath_span } => ( qpath_id, qpath_span) ,
3471
3506
} ;
3472
3507
3473
3508
let first_name = match path. get ( 0 ) {
@@ -4536,6 +4571,11 @@ enum CrateLint {
4536
4571
/// have nested things like `use a::{b, c}`, we care about the
4537
4572
/// `use a` part.
4538
4573
UsePath { root_id : NodeId , root_span : Span } ,
4574
+
4575
+ /// This is the "trait item" from a fully qualified path. For example,
4576
+ /// we might be resolving `X::Y::Z` from a path like `<T as X::Y>::Z`.
4577
+ /// The `path_span` is the span of the to the trait itself (`X::Y`).
4578
+ QPathTrait { qpath_id : NodeId , qpath_span : Span } ,
4539
4579
}
4540
4580
4541
4581
__build_diagnostic_array ! { librustc_resolve, DIAGNOSTICS }
0 commit comments