aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs89
1 files changed, 28 insertions, 61 deletions
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index cf93205b6..e29f65a78 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -565,29 +565,21 @@ fn highlight_element(
565 _ => h, 565 _ => h,
566 } 566 }
567 } 567 }
568 T![&] => {
569 let ref_expr = element.parent().and_then(ast::RefExpr::cast)?;
570 let expr = ref_expr.expr()?;
571 let field_expr = match expr {
572 ast::Expr::FieldExpr(fe) => fe,
573 _ => return None,
574 };
575
576 let expr = field_expr.expr()?;
577 let ty = sema.type_of_expr(&expr)?;
578 if !ty.is_packed(db) {
579 return None;
580 }
581
582 // FIXME This needs layout computation to be correct. It will highlight
583 // more than it should with the current implementation.
584
585 HighlightTag::Operator | HighlightModifier::Unsafe
586 }
587 p if p.is_punct() => match p { 568 p if p.is_punct() => match p {
588 T![::] | T![->] | T![=>] | T![&] | T![..] | T![=] | T![@] => { 569 T![&] => {
589 HighlightTag::Operator.into() 570 let h = HighlightTag::Operator.into();
571 let is_unsafe = element
572 .parent()
573 .and_then(ast::RefExpr::cast)
574 .map(|ref_expr| sema.is_unsafe_ref_expr(&ref_expr))
575 .unwrap_or(false);
576 if is_unsafe {
577 h | HighlightModifier::Unsafe
578 } else {
579 h
580 }
590 } 581 }
582 T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] => HighlightTag::Operator.into(),
591 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { 583 T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => {
592 HighlightTag::Macro.into() 584 HighlightTag::Macro.into()
593 } 585 }
@@ -668,22 +660,18 @@ fn highlight_element(
668 HighlightTag::SelfKeyword.into() 660 HighlightTag::SelfKeyword.into()
669 } 661 }
670 } 662 }
671 T![ref] => { 663 T![ref] => element
672 let modifier: Option<HighlightModifier> = (|| { 664 .parent()
673 let bind_pat = element.parent().and_then(ast::BindPat::cast)?; 665 .and_then(ast::BindPat::cast)
674 if sema.is_unsafe_pat(&ast::Pat::BindPat(bind_pat)) { 666 .and_then(|bind_pat| {
667 if sema.is_unsafe_bind_pat(&bind_pat) {
675 Some(HighlightModifier::Unsafe) 668 Some(HighlightModifier::Unsafe)
676 } else { 669 } else {
677 None 670 None
678 } 671 }
679 })(); 672 })
680 673 .map(|modifier| h | modifier)
681 if let Some(modifier) = modifier { 674 .unwrap_or(h),
682 h | modifier
683 } else {
684 h
685 }
686 }
687 _ => h, 675 _ => h,
688 } 676 }
689 } 677 }
@@ -713,31 +701,6 @@ fn is_child_of_impl(element: &SyntaxElement) -> bool {
713 } 701 }
714} 702}
715 703
716fn is_method_call_unsafe(
717 sema: &Semantics<RootDatabase>,
718 method_call_expr: ast::MethodCallExpr,
719) -> Option<()> {
720 let expr = method_call_expr.expr()?;
721 let field_expr =
722 if let ast::Expr::FieldExpr(field_expr) = expr { field_expr } else { return None };
723 let ty = sema.type_of_expr(&field_expr.expr()?)?;
724 if !ty.is_packed(sema.db) {
725 return None;
726 }
727
728 let func = sema.resolve_method_call(&method_call_expr)?;
729 if func.has_self_param(sema.db) {
730 let params = func.params(sema.db);
731 if matches!(params.into_iter().next(), Some(TypeRef::Reference(..))) {
732 Some(())
733 } else {
734 None
735 }
736 } else {
737 None
738 }
739}
740
741fn highlight_name( 704fn highlight_name(
742 sema: &Semantics<RootDatabase>, 705 sema: &Semantics<RootDatabase>,
743 db: &RootDatabase, 706 db: &RootDatabase,
@@ -767,7 +730,7 @@ fn highlight_name(
767 let is_unsafe = name_ref 730 let is_unsafe = name_ref
768 .and_then(|name_ref| name_ref.syntax().parent()) 731 .and_then(|name_ref| name_ref.syntax().parent())
769 .and_then(ast::MethodCallExpr::cast) 732 .and_then(ast::MethodCallExpr::cast)
770 .and_then(|method_call_expr| is_method_call_unsafe(sema, method_call_expr)); 733 .and_then(|method_call_expr| sema.is_unsafe_method_call(method_call_expr));
771 if is_unsafe.is_some() { 734 if is_unsafe.is_some() {
772 h |= HighlightModifier::Unsafe; 735 h |= HighlightModifier::Unsafe;
773 } 736 }
@@ -846,7 +809,7 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
846 METHOD_CALL_EXPR => { 809 METHOD_CALL_EXPR => {
847 let mut h = Highlight::new(HighlightTag::Function); 810 let mut h = Highlight::new(HighlightTag::Function);
848 let is_unsafe = ast::MethodCallExpr::cast(parent) 811 let is_unsafe = ast::MethodCallExpr::cast(parent)
849 .and_then(|method_call_expr| is_method_call_unsafe(sema, method_call_expr)); 812 .and_then(|method_call_expr| sema.is_unsafe_method_call(method_call_expr));
850 813
851 if is_unsafe.is_some() { 814 if is_unsafe.is_some() {
852 h |= HighlightModifier::Unsafe; 815 h |= HighlightModifier::Unsafe;
@@ -866,7 +829,11 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
866 }) 829 })
867 }) 830 })
868 .unwrap_or(false); 831 .unwrap_or(false);
869 if is_union { h | HighlightModifier::Unsafe } else { h.into() } 832 if is_union {
833 h | HighlightModifier::Unsafe
834 } else {
835 h.into()
836 }
870 } 837 }
871 PATH_SEGMENT => { 838 PATH_SEGMENT => {
872 let path = match parent.parent().and_then(ast::Path::cast) { 839 let path = match parent.parent().and_then(ast::Path::cast) {