@@ -56,7 +56,7 @@ pub(crate) struct CompletionContext<'a> {
56
56
/// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
57
57
pub ( super ) is_trivial_path : bool ,
58
58
/// If not a trivial path, the prefix (qualifier).
59
- pub ( super ) path_prefix : Option < hir :: Path > ,
59
+ pub ( super ) path_qual : Option < ast :: Path > ,
60
60
pub ( super ) after_if : bool ,
61
61
/// `true` if we are a statement or a last expr in the block.
62
62
pub ( super ) can_be_stmt : bool ,
@@ -137,7 +137,7 @@ impl<'a> CompletionContext<'a> {
137
137
is_param : false ,
138
138
is_pat_binding_or_const : false ,
139
139
is_trivial_path : false ,
140
- path_prefix : None ,
140
+ path_qual : None ,
141
141
after_if : false ,
142
142
can_be_stmt : false ,
143
143
is_expr : false ,
@@ -385,48 +385,54 @@ impl<'a> CompletionContext<'a> {
385
385
self . is_path_type = path. syntax ( ) . parent ( ) . and_then ( ast:: PathType :: cast) . is_some ( ) ;
386
386
self . has_type_args = segment. generic_arg_list ( ) . is_some ( ) ;
387
387
388
- let hygiene = hir:: Hygiene :: new ( self . db , self . position . file_id . into ( ) ) ;
389
- if let Some ( path) = hir:: Path :: from_src ( path. clone ( ) , & hygiene) {
390
- if let Some ( path_prefix) = path. qualifier ( ) {
391
- self . path_prefix = Some ( path_prefix) ;
388
+ if let Some ( path) = path_or_use_tree_qualifier ( & path) {
389
+ self . path_qual = path
390
+ . segment ( )
391
+ . and_then ( |it| {
392
+ find_node_with_range :: < ast:: PathSegment > (
393
+ original_file,
394
+ it. syntax ( ) . text_range ( ) ,
395
+ )
396
+ } )
397
+ . map ( |it| it. parent_path ( ) ) ;
398
+ return ;
399
+ }
400
+
401
+ if let Some ( segment) = path. segment ( ) {
402
+ if segment. coloncolon_token ( ) . is_some ( ) {
392
403
return ;
393
404
}
394
405
}
395
406
396
- if path. qualifier ( ) . is_none ( ) {
397
- self . is_trivial_path = true ;
398
-
399
- // Find either enclosing expr statement (thing with `;`) or a
400
- // block. If block, check that we are the last expr.
401
- self . can_be_stmt = name_ref
402
- . syntax ( )
403
- . ancestors ( )
404
- . find_map ( |node| {
405
- if let Some ( stmt) = ast:: ExprStmt :: cast ( node. clone ( ) ) {
406
- return Some (
407
- stmt. syntax ( ) . text_range ( ) == name_ref. syntax ( ) . text_range ( ) ,
408
- ) ;
409
- }
410
- if let Some ( block) = ast:: BlockExpr :: cast ( node) {
411
- return Some (
412
- block. expr ( ) . map ( |e| e. syntax ( ) . text_range ( ) )
413
- == Some ( name_ref. syntax ( ) . text_range ( ) ) ,
414
- ) ;
415
- }
416
- None
417
- } )
418
- . unwrap_or ( false ) ;
419
- self . is_expr = path. syntax ( ) . parent ( ) . and_then ( ast:: PathExpr :: cast) . is_some ( ) ;
407
+ self . is_trivial_path = true ;
420
408
421
- if let Some ( off) = name_ref. syntax ( ) . text_range ( ) . start ( ) . checked_sub ( 2 . into ( ) ) {
422
- if let Some ( if_expr) =
423
- self . sema . find_node_at_offset_with_macros :: < ast:: IfExpr > ( original_file, off)
409
+ // Find either enclosing expr statement (thing with `;`) or a
410
+ // block. If block, check that we are the last expr.
411
+ self . can_be_stmt = name_ref
412
+ . syntax ( )
413
+ . ancestors ( )
414
+ . find_map ( |node| {
415
+ if let Some ( stmt) = ast:: ExprStmt :: cast ( node. clone ( ) ) {
416
+ return Some ( stmt. syntax ( ) . text_range ( ) == name_ref. syntax ( ) . text_range ( ) ) ;
417
+ }
418
+ if let Some ( block) = ast:: BlockExpr :: cast ( node) {
419
+ return Some (
420
+ block. expr ( ) . map ( |e| e. syntax ( ) . text_range ( ) )
421
+ == Some ( name_ref. syntax ( ) . text_range ( ) ) ,
422
+ ) ;
423
+ }
424
+ None
425
+ } )
426
+ . unwrap_or ( false ) ;
427
+ self . is_expr = path. syntax ( ) . parent ( ) . and_then ( ast:: PathExpr :: cast) . is_some ( ) ;
428
+
429
+ if let Some ( off) = name_ref. syntax ( ) . text_range ( ) . start ( ) . checked_sub ( 2 . into ( ) ) {
430
+ if let Some ( if_expr) =
431
+ self . sema . find_node_at_offset_with_macros :: < ast:: IfExpr > ( original_file, off)
432
+ {
433
+ if if_expr. syntax ( ) . text_range ( ) . end ( ) < name_ref. syntax ( ) . text_range ( ) . start ( )
424
434
{
425
- if if_expr. syntax ( ) . text_range ( ) . end ( )
426
- < name_ref. syntax ( ) . text_range ( ) . start ( )
427
- {
428
- self . after_if = true ;
429
- }
435
+ self . after_if = true ;
430
436
}
431
437
}
432
438
}
@@ -469,3 +475,12 @@ fn is_node<N: AstNode>(node: &SyntaxNode) -> bool {
469
475
Some ( n) => n. syntax ( ) . text_range ( ) == node. text_range ( ) ,
470
476
}
471
477
}
478
+
479
+ fn path_or_use_tree_qualifier ( path : & ast:: Path ) -> Option < ast:: Path > {
480
+ if let Some ( qual) = path. qualifier ( ) {
481
+ return Some ( qual) ;
482
+ }
483
+ let use_tree_list = path. syntax ( ) . ancestors ( ) . find_map ( ast:: UseTreeList :: cast) ?;
484
+ let use_tree = use_tree_list. syntax ( ) . parent ( ) . and_then ( ast:: UseTree :: cast) ?;
485
+ use_tree. path ( )
486
+ }
0 commit comments