aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-08-08 17:45:37 +0100
committerGitHub <[email protected]>2020-08-08 17:45:37 +0100
commit8a57afe5a4bfab40072a83f7dc4ca560bf860919 (patch)
tree167d3717945c94c7523bbda5018239ed3a1c5fca /crates/ra_ide
parenteed05a95b47c00bf6ce06e156716cd0648a88fb2 (diff)
parentbe935b2b56dcbda5a5918d8c600552b0adbb3a96 (diff)
Merge #5684
5684: Semantic highlighting for unsafe union field access r=jonas-schievink a=Nashenas88 This change adds support for unions in inference and lowering, then extends on that to add the unsafe semantic modifier on field access only. The `is_possibly_unsafe` function in `syntax_highlighting.rs` could be extended to support fns and static muts so that their definitions are not highlighted as unsafe, but only their usage. Also, each commit of this PR updates the tests. By reviewing the files by commit, it's easy to see how the changes in the code affected the tests. Co-authored-by: Paul Daniel Faria <[email protected]>
Diffstat (limited to 'crates/ra_ide')
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs66
-rw-r--r--crates/ra_ide/src/syntax_highlighting/tests.rs11
-rw-r--r--crates/ra_ide/test_data/highlight_unsafe.html11
3 files changed, 78 insertions, 10 deletions
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index 89efe71da..f71b804fe 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -4,7 +4,7 @@ mod injection;
4#[cfg(test)] 4#[cfg(test)]
5mod tests; 5mod tests;
6 6
7use hir::{Name, Semantics}; 7use hir::{Name, Semantics, VariantDef};
8use ra_ide_db::{ 8use ra_ide_db::{
9 defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass}, 9 defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass},
10 RootDatabase, 10 RootDatabase,
@@ -455,6 +455,18 @@ fn macro_call_range(macro_call: &ast::MacroCall) -> Option<TextRange> {
455 Some(TextRange::new(range_start, range_end)) 455 Some(TextRange::new(range_start, range_end))
456} 456}
457 457
458fn 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
458fn highlight_element( 470fn highlight_element(
459 sema: &Semantics<RootDatabase>, 471 sema: &Semantics<RootDatabase>,
460 bindings_shadow_count: &mut FxHashMap<Name, u32>, 472 bindings_shadow_count: &mut FxHashMap<Name, u32>,
@@ -484,10 +496,19 @@ fn highlight_element(
484 496
485 match name_kind { 497 match name_kind {
486 Some(NameClass::Definition(def)) => { 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 None => highlight_name_by_syntax(name) | HighlightModifier::Definition, 512 None => highlight_name_by_syntax(name) | HighlightModifier::Definition,
492 } 513 }
493 } 514 }
@@ -498,6 +519,7 @@ fn highlight_element(
498 } 519 }
499 NAME_REF => { 520 NAME_REF => {
500 let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); 521 let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap();
522 let possibly_unsafe = is_possibly_unsafe(&name_ref);
501 match classify_name_ref(sema, &name_ref) { 523 match classify_name_ref(sema, &name_ref) {
502 Some(name_kind) => match name_kind { 524 Some(name_kind) => match name_kind {
503 NameRefClass::Definition(def) => { 525 NameRefClass::Definition(def) => {
@@ -508,11 +530,13 @@ fn highlight_element(
508 binding_hash = Some(calc_binding_hash(&name, *shadow_count)) 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 NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(), 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 None => HighlightTag::UnresolvedReference.into(), 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
655fn highlight_name(db: &RootDatabase, def: Definition) -> Highlight { 679fn highlight_name(db: &RootDatabase, def: Definition, possibly_unsafe: bool) -> Highlight {
656 match def { 680 match def {
657 Definition::Macro(_) => HighlightTag::Macro, 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 Definition::ModuleDef(def) => match def { 692 Definition::ModuleDef(def) => match def {
660 hir::ModuleDef::Module(_) => HighlightTag::Module, 693 hir::ModuleDef::Module(_) => HighlightTag::Module,
661 hir::ModuleDef::Function(func) => { 694 hir::ModuleDef::Function(func) => {
@@ -725,7 +758,7 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight {
725 tag.into() 758 tag.into()
726} 759}
727 760
728fn highlight_name_ref_by_syntax(name: ast::NameRef) -> Highlight { 761fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabase>) -> Highlight {
729 let default = HighlightTag::UnresolvedReference; 762 let default = HighlightTag::UnresolvedReference;
730 763
731 let parent = match name.syntax().parent() { 764 let parent = match name.syntax().parent() {
@@ -735,7 +768,20 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef) -> Highlight {
735 768
736 let tag = match parent.kind() { 769 let tag = match parent.kind() {
737 METHOD_CALL_EXPR => HighlightTag::Function, 770 METHOD_CALL_EXPR => HighlightTag::Function,
738 FIELD_EXPR => HighlightTag::Field, 771 FIELD_EXPR => {
772 let h = HighlightTag::Field;
773 let is_union = ast::FieldExpr::cast(parent)
774 .and_then(|field_expr| {
775 let field = sema.resolve_field(&field_expr)?;
776 Some(if let VariantDef::Union(_) = field.parent_def(sema.db) {
777 true
778 } else {
779 false
780 })
781 })
782 .unwrap_or(false);
783 return if is_union { h | HighlightModifier::Unsafe } else { h.into() };
784 }
739 PATH_SEGMENT => { 785 PATH_SEGMENT => {
740 let path = match parent.parent().and_then(ast::Path::cast) { 786 let path = match parent.parent().and_then(ast::Path::cast) {
741 Some(it) => it, 787 Some(it) => it,
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs
index b9b358022..730efff0d 100644
--- a/crates/ra_ide/src/syntax_highlighting/tests.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tests.rs
@@ -275,6 +275,11 @@ fn test_unsafe_highlighting() {
275 r#" 275 r#"
276unsafe fn unsafe_fn() {} 276unsafe fn unsafe_fn() {}
277 277
278union Union {
279 a: u32,
280 b: f32,
281}
282
278struct HasUnsafeFn; 283struct HasUnsafeFn;
279 284
280impl HasUnsafeFn { 285impl HasUnsafeFn {
@@ -289,8 +294,14 @@ static mut global_mut: TypeForStaticMut = TypeForStaticMut { a: 0 };
289 294
290fn main() { 295fn main() {
291 let x = &5 as *const usize; 296 let x = &5 as *const usize;
297 let u = Union { b: 0 };
292 unsafe { 298 unsafe {
293 unsafe_fn(); 299 unsafe_fn();
300 let b = u.b;
301 match u {
302 Union { b: 0 } => (),
303 Union { a } => (),
304 }
294 HasUnsafeFn.unsafe_method(); 305 HasUnsafeFn.unsafe_method();
295 let y = *(x); 306 let y = *(x);
296 let z = -x; 307 let z = -x;
diff --git a/crates/ra_ide/test_data/highlight_unsafe.html b/crates/ra_ide/test_data/highlight_unsafe.html
index 87d8c1556..79409fe81 100644
--- a/crates/ra_ide/test_data/highlight_unsafe.html
+++ b/crates/ra_ide/test_data/highlight_unsafe.html
@@ -37,6 +37,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
37</style> 37</style>
38<pre><code><span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration unsafe">unsafe_fn</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> 38<pre><code><span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration unsafe">unsafe_fn</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
39 39
40<span class="keyword">union</span> <span class="union declaration">Union</span> <span class="punctuation">{</span>
41 <span class="field declaration">a</span><span class="punctuation">:</span> <span class="builtin_type">u32</span><span class="punctuation">,</span>
42 <span class="field declaration">b</span><span class="punctuation">:</span> <span class="builtin_type">f32</span><span class="punctuation">,</span>
43<span class="punctuation">}</span>
44
40<span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="punctuation">;</span> 45<span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="punctuation">;</span>
41 46
42<span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="punctuation">{</span> 47<span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="punctuation">{</span>
@@ -51,8 +56,14 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
51 56
52<span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> 57<span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
53 <span class="keyword">let</span> <span class="variable declaration">x</span> <span class="operator">=</span> <span class="operator">&</span><span class="numeric_literal">5</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="builtin_type">usize</span><span class="punctuation">;</span> 58 <span class="keyword">let</span> <span class="variable declaration">x</span> <span class="operator">=</span> <span class="operator">&</span><span class="numeric_literal">5</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="builtin_type">usize</span><span class="punctuation">;</span>
59 <span class="keyword">let</span> <span class="variable declaration">u</span> <span class="operator">=</span> <span class="union">Union</span> <span class="punctuation">{</span> <span class="field">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span><span class="punctuation">;</span>
54 <span class="keyword unsafe">unsafe</span> <span class="punctuation">{</span> 60 <span class="keyword unsafe">unsafe</span> <span class="punctuation">{</span>
55 <span class="function unsafe">unsafe_fn</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> 61 <span class="function unsafe">unsafe_fn</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
62 <span class="keyword">let</span> <span class="variable declaration">b</span> <span class="operator">=</span> <span class="variable">u</span><span class="punctuation">.</span><span class="field unsafe">b</span><span class="punctuation">;</span>
63 <span class="keyword control">match</span> <span class="variable">u</span> <span class="punctuation">{</span>
64 <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span> <span class="operator">=&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
65 <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">a</span> <span class="punctuation">}</span> <span class="operator">=&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
66 <span class="punctuation">}</span>
56 <span class="struct">HasUnsafeFn</span><span class="punctuation">.</span><span class="function unsafe">unsafe_method</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> 67 <span class="struct">HasUnsafeFn</span><span class="punctuation">.</span><span class="function unsafe">unsafe_method</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
57 <span class="keyword">let</span> <span class="variable declaration">y</span> <span class="operator">=</span> <span class="operator unsafe">*</span><span class="punctuation">(</span><span class="variable">x</span><span class="punctuation">)</span><span class="punctuation">;</span> 68 <span class="keyword">let</span> <span class="variable declaration">y</span> <span class="operator">=</span> <span class="operator unsafe">*</span><span class="punctuation">(</span><span class="variable">x</span><span class="punctuation">)</span><span class="punctuation">;</span>
58 <span class="keyword">let</span> <span class="variable declaration">z</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="variable">x</span><span class="punctuation">;</span> 69 <span class="keyword">let</span> <span class="variable declaration">z</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="variable">x</span><span class="punctuation">;</span>