@@ -4,7 +4,7 @@ mod injection;
4
4
#[ cfg( test) ]
5
5
mod tests;
6
6
7
- use hir:: { Name , Semantics } ;
7
+ use hir:: { Name , Semantics , VariantDef } ;
8
8
use ra_ide_db:: {
9
9
defs:: { classify_name, classify_name_ref, Definition , NameClass , NameRefClass } ,
10
10
RootDatabase ,
@@ -455,6 +455,18 @@ fn macro_call_range(macro_call: &ast::MacroCall) -> Option<TextRange> {
455
455
Some ( TextRange :: new ( range_start, range_end) )
456
456
}
457
457
458
+ fn is_possibly_unsafe ( name_ref : & ast:: NameRef ) -> bool {
459
+ name_ref
460
+ . syntax ( )
461
+ . parent ( )
462
+ . and_then ( |parent| {
463
+ ast:: FieldExpr :: cast ( parent. clone ( ) )
464
+ . map ( |_| true )
465
+ . or_else ( || ast:: RecordPatField :: cast ( parent) . map ( |_| true ) )
466
+ } )
467
+ . unwrap_or ( false )
468
+ }
469
+
458
470
fn highlight_element (
459
471
sema : & Semantics < RootDatabase > ,
460
472
bindings_shadow_count : & mut FxHashMap < Name , u32 > ,
@@ -484,10 +496,19 @@ fn highlight_element(
484
496
485
497
match name_kind {
486
498
Some ( NameClass :: Definition ( def) ) => {
487
- highlight_name ( db, def) | HighlightModifier :: Definition
499
+ highlight_name ( db, def, false ) | HighlightModifier :: Definition
500
+ }
501
+ Some ( NameClass :: ConstReference ( def) ) => highlight_name ( db, def, false ) ,
502
+ Some ( NameClass :: FieldShorthand { field, .. } ) => {
503
+ let mut h = HighlightTag :: Field . into ( ) ;
504
+ if let Definition :: Field ( field) = field {
505
+ if let VariantDef :: Union ( _) = field. parent_def ( db) {
506
+ h |= HighlightModifier :: Unsafe ;
507
+ }
508
+ }
509
+
510
+ h
488
511
}
489
- Some ( NameClass :: ConstReference ( def) ) => highlight_name ( db, def) ,
490
- Some ( NameClass :: FieldShorthand { .. } ) => HighlightTag :: Field . into ( ) ,
491
512
None => highlight_name_by_syntax ( name) | HighlightModifier :: Definition ,
492
513
}
493
514
}
@@ -498,6 +519,7 @@ fn highlight_element(
498
519
}
499
520
NAME_REF => {
500
521
let name_ref = element. into_node ( ) . and_then ( ast:: NameRef :: cast) . unwrap ( ) ;
522
+ let possibly_unsafe = is_possibly_unsafe ( & name_ref) ;
501
523
match classify_name_ref ( sema, & name_ref) {
502
524
Some ( name_kind) => match name_kind {
503
525
NameRefClass :: Definition ( def) => {
@@ -508,11 +530,13 @@ fn highlight_element(
508
530
binding_hash = Some ( calc_binding_hash ( & name, * shadow_count) )
509
531
}
510
532
} ;
511
- highlight_name ( db, def)
533
+ highlight_name ( db, def, possibly_unsafe )
512
534
}
513
535
NameRefClass :: FieldShorthand { .. } => HighlightTag :: Field . into ( ) ,
514
536
} ,
515
- None if syntactic_name_ref_highlighting => highlight_name_ref_by_syntax ( name_ref) ,
537
+ None if syntactic_name_ref_highlighting => {
538
+ highlight_name_ref_by_syntax ( name_ref, sema)
539
+ }
516
540
None => HighlightTag :: UnresolvedReference . into ( ) ,
517
541
}
518
542
}
@@ -652,10 +676,19 @@ fn is_child_of_impl(element: &SyntaxElement) -> bool {
652
676
}
653
677
}
654
678
655
- fn highlight_name ( db : & RootDatabase , def : Definition ) -> Highlight {
679
+ fn highlight_name ( db : & RootDatabase , def : Definition , possibly_unsafe : bool ) -> Highlight {
656
680
match def {
657
681
Definition :: Macro ( _) => HighlightTag :: Macro ,
658
- Definition :: Field ( _) => HighlightTag :: Field ,
682
+ Definition :: Field ( field) => {
683
+ let mut h = HighlightTag :: Field . into ( ) ;
684
+ if possibly_unsafe {
685
+ if let VariantDef :: Union ( _) = field. parent_def ( db) {
686
+ h |= HighlightModifier :: Unsafe ;
687
+ }
688
+ }
689
+
690
+ return h;
691
+ }
659
692
Definition :: ModuleDef ( def) => match def {
660
693
hir:: ModuleDef :: Module ( _) => HighlightTag :: Module ,
661
694
hir:: ModuleDef :: Function ( func) => {
@@ -724,7 +757,7 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight {
724
757
tag. into ( )
725
758
}
726
759
727
- fn highlight_name_ref_by_syntax ( name : ast:: NameRef ) -> Highlight {
760
+ fn highlight_name_ref_by_syntax ( name : ast:: NameRef , sema : & Semantics < RootDatabase > ) -> Highlight {
728
761
let default = HighlightTag :: UnresolvedReference ;
729
762
730
763
let parent = match name. syntax ( ) . parent ( ) {
@@ -734,7 +767,20 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef) -> Highlight {
734
767
735
768
let tag = match parent. kind ( ) {
736
769
METHOD_CALL_EXPR => HighlightTag :: Function ,
737
- FIELD_EXPR => HighlightTag :: Field ,
770
+ FIELD_EXPR => {
771
+ let h = HighlightTag :: Field ;
772
+ let is_union = ast:: FieldExpr :: cast ( parent)
773
+ . and_then ( |field_expr| {
774
+ let field = sema. resolve_field ( & field_expr) ?;
775
+ Some ( if let VariantDef :: Union ( _) = field. parent_def ( sema. db ) {
776
+ true
777
+ } else {
778
+ false
779
+ } )
780
+ } )
781
+ . unwrap_or ( false ) ;
782
+ return if is_union { h | HighlightModifier :: Unsafe } else { h. into ( ) } ;
783
+ }
738
784
PATH_SEGMENT => {
739
785
let path = match parent. parent ( ) . and_then ( ast:: Path :: cast) {
740
786
Some ( it) => it,
0 commit comments