Skip to content

Commit a9cb293

Browse files
committed
Add highlight support for unsafe fn calls and raw ptr deref
1 parent 2f6ab77 commit a9cb293

File tree

11 files changed

+125
-6
lines changed

11 files changed

+125
-6
lines changed

crates/ra_hir/src/code_model.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,10 @@ impl Function {
637637
db.function_data(self.id).params.clone()
638638
}
639639

640+
pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
641+
db.function_data(self.id).is_unsafe
642+
}
643+
640644
pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
641645
let _p = profile("Function::diagnostics");
642646
let infer = db.infer(self.id.into());
@@ -1190,6 +1194,10 @@ impl Type {
11901194
)
11911195
}
11921196

1197+
pub fn is_raw_ptr(&self) -> bool {
1198+
matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. }))
1199+
}
1200+
11931201
pub fn contains_unknown(&self) -> bool {
11941202
return go(&self.ty.value);
11951203

crates/ra_hir_def/src/data.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub struct FunctionData {
3434
/// True if the first param is `self`. This is relevant to decide whether this
3535
/// can be called as a method.
3636
pub has_self_param: bool,
37+
pub is_unsafe: bool,
3738
pub visibility: RawVisibility,
3839
}
3940

@@ -85,11 +86,14 @@ impl FunctionData {
8586
ret_type
8687
};
8788

89+
let is_unsafe = src.value.unsafe_token().is_some();
90+
8891
let vis_default = RawVisibility::default_for_container(loc.container);
8992
let visibility =
9093
RawVisibility::from_ast_with_default(db, vis_default, src.map(|s| s.visibility()));
9194

92-
let sig = FunctionData { name, params, ret_type, has_self_param, visibility, attrs };
95+
let sig =
96+
FunctionData { name, params, ret_type, has_self_param, is_unsafe, visibility, attrs };
9397
Arc::new(sig)
9498
}
9599
}

crates/ra_ide/src/snapshots/highlight_injection.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
.string_literal { color: #CC9393; }
1111
.field { color: #94BFF3; }
1212
.function { color: #93E0E3; }
13+
.operator.unsafe { color: #E28C14; }
1314
.parameter { color: #94BFF3; }
1415
.text { color: #DCDCCC; }
1516
.type { color: #7CB8BB; }

crates/ra_ide/src/snapshots/highlight_strings.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
.string_literal { color: #CC9393; }
1111
.field { color: #94BFF3; }
1212
.function { color: #93E0E3; }
13+
.operator.unsafe { color: #E28C14; }
1314
.parameter { color: #94BFF3; }
1415
.text { color: #DCDCCC; }
1516
.type { color: #7CB8BB; }
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
2+
<style>
3+
body { margin: 0; }
4+
pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
5+
6+
.lifetime { color: #DFAF8F; font-style: italic; }
7+
.comment { color: #7F9F7F; }
8+
.struct, .enum { color: #7CB8BB; }
9+
.enum_variant { color: #BDE0F3; }
10+
.string_literal { color: #CC9393; }
11+
.field { color: #94BFF3; }
12+
.function { color: #93E0E3; }
13+
.operator.unsafe { color: #E28C14; }
14+
.parameter { color: #94BFF3; }
15+
.text { color: #DCDCCC; }
16+
.type { color: #7CB8BB; }
17+
.builtin_type { color: #8CD0D3; }
18+
.type_param { color: #DFAF8F; }
19+
.attribute { color: #94BFF3; }
20+
.numeric_literal { color: #BFEBBF; }
21+
.bool_literal { color: #BFE6EB; }
22+
.macro { color: #94BFF3; }
23+
.module { color: #AFD8AF; }
24+
.variable { color: #DCDCCC; }
25+
.format_specifier { color: #CC696B; }
26+
.mutable { text-decoration: underline; }
27+
28+
.keyword { color: #F0DFAF; font-weight: bold; }
29+
.keyword.unsafe { color: #BC8383; font-weight: bold; }
30+
.control { font-style: italic; }
31+
</style>
32+
<pre><code><span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration unsafe">unsafe_fn</span>() {}
33+
34+
<span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span>;
35+
36+
<span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> {
37+
<span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration unsafe">unsafe_method</span>(&<span class="self_keyword">self</span>) {}
38+
}
39+
40+
<span class="keyword">fn</span> <span class="function declaration">main</span>() {
41+
<span class="keyword">let</span> <span class="variable declaration">x</span> = &<span class="numeric_literal">5</span> <span class="keyword">as</span> *<span class="keyword">const</span> <span class="builtin_type">usize</span>;
42+
<span class="keyword unsafe">unsafe</span> {
43+
<span class="function unsafe">unsafe_fn</span>();
44+
<span class="struct">HasUnsafeFn</span>.<span class="function unsafe">unsafe_method</span>();
45+
<span class="keyword">let</span> <span class="variable declaration">y</span> = <span class="operator unsafe">*</span><span class="variable">x</span>;
46+
<span class="keyword">let</span> <span class="variable declaration">z</span> = -<span class="variable">x</span>;
47+
}
48+
}</code></pre>

crates/ra_ide/src/snapshots/highlighting.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
.string_literal { color: #CC9393; }
1111
.field { color: #94BFF3; }
1212
.function { color: #93E0E3; }
13+
.operator.unsafe { color: #E28C14; }
1314
.parameter { color: #94BFF3; }
1415
.text { color: #DCDCCC; }
1516
.type { color: #7CB8BB; }

crates/ra_ide/src/snapshots/rainbow_highlighting.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
.string_literal { color: #CC9393; }
1111
.field { color: #94BFF3; }
1212
.function { color: #93E0E3; }
13+
.operator.unsafe { color: #E28C14; }
1314
.parameter { color: #94BFF3; }
1415
.text { color: #DCDCCC; }
1516
.type { color: #7CB8BB; }

crates/ra_ide/src/syntax_highlighting.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,23 @@ fn highlight_element(
406406
_ => h,
407407
}
408408
}
409+
PREFIX_EXPR => {
410+
let prefix_expr = element.into_node().and_then(ast::PrefixExpr::cast)?;
411+
match prefix_expr.op_kind() {
412+
Some(ast::PrefixOp::Deref) => {}
413+
_ => return None,
414+
}
415+
416+
let expr = prefix_expr.expr()?;
417+
let ty = sema.type_of_expr(&expr)?;
418+
if !ty.is_raw_ptr() {
419+
return None;
420+
}
421+
422+
let mut h = Highlight::new(HighlightTag::Operator);
423+
h |= HighlightModifier::Unsafe;
424+
h
425+
}
409426

410427
k if k.is_keyword() => {
411428
let h = Highlight::new(HighlightTag::Keyword);
@@ -458,7 +475,13 @@ fn highlight_name(db: &RootDatabase, def: Definition) -> Highlight {
458475
Definition::Field(_) => HighlightTag::Field,
459476
Definition::ModuleDef(def) => match def {
460477
hir::ModuleDef::Module(_) => HighlightTag::Module,
461-
hir::ModuleDef::Function(_) => HighlightTag::Function,
478+
hir::ModuleDef::Function(func) => {
479+
let mut h = HighlightTag::Function.into();
480+
if func.is_unsafe(db) {
481+
h |= HighlightModifier::Unsafe;
482+
}
483+
return h;
484+
}
462485
hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct,
463486
hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum,
464487
hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union,

crates/ra_ide/src/syntax_highlighting/html.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
6969
.string_literal { color: #CC9393; }
7070
.field { color: #94BFF3; }
7171
.function { color: #93E0E3; }
72+
.operator.unsafe { color: #E28C14; }
7273
.parameter { color: #94BFF3; }
7374
.text { color: #DCDCCC; }
7475
.type { color: #7CB8BB; }

crates/ra_ide/src/syntax_highlighting/tags.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ pub enum HighlightTag {
2424
Enum,
2525
EnumVariant,
2626
Field,
27+
FormatSpecifier,
2728
Function,
2829
Keyword,
2930
Lifetime,
3031
Macro,
3132
Module,
3233
NumericLiteral,
34+
Operator,
3335
SelfKeyword,
3436
SelfType,
3537
Static,
@@ -41,8 +43,6 @@ pub enum HighlightTag {
4143
Union,
4244
Local,
4345
UnresolvedReference,
44-
FormatSpecifier,
45-
Operator,
4646
}
4747

4848
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
@@ -72,12 +72,14 @@ impl HighlightTag {
7272
HighlightTag::Enum => "enum",
7373
HighlightTag::EnumVariant => "enum_variant",
7474
HighlightTag::Field => "field",
75+
HighlightTag::FormatSpecifier => "format_specifier",
7576
HighlightTag::Function => "function",
7677
HighlightTag::Keyword => "keyword",
7778
HighlightTag::Lifetime => "lifetime",
7879
HighlightTag::Macro => "macro",
7980
HighlightTag::Module => "module",
8081
HighlightTag::NumericLiteral => "numeric_literal",
82+
HighlightTag::Operator => "operator",
8183
HighlightTag::SelfKeyword => "self_keyword",
8284
HighlightTag::SelfType => "self_type",
8385
HighlightTag::Static => "static",
@@ -89,8 +91,6 @@ impl HighlightTag {
8991
HighlightTag::Union => "union",
9092
HighlightTag::Local => "variable",
9193
HighlightTag::UnresolvedReference => "unresolved_reference",
92-
HighlightTag::FormatSpecifier => "format_specifier",
93-
HighlightTag::Operator => "operator",
9494
}
9595
}
9696
}

0 commit comments

Comments
 (0)