From 263f9a7f231a474dd56d02adbcd7c57d079e88fd Mon Sep 17 00:00:00 2001 From: Paul Daniel Faria Date: Wed, 3 Jun 2020 23:38:25 -0400 Subject: Add tracking of packed repr, use it to highlight unsafe refs Taking a reference to a misaligned field on a packed struct is an unsafe operation. Highlight that behavior. Currently, the misaligned part isn't tracked, so this highlight is a bit too aggressive. --- crates/ra_ide/src/syntax_highlighting.rs | 24 ++++++++++++++++++++++++ crates/ra_ide/src/syntax_highlighting/tests.rs | 11 +++++++++++ 2 files changed, 35 insertions(+) (limited to 'crates/ra_ide') diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 6b7874460..0cab684eb 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -565,6 +565,30 @@ fn highlight_element( _ => h, } } + REF_EXPR => { + let ref_expr = element.into_node().and_then(ast::RefExpr::cast)?; + let expr = ref_expr.expr()?; + let field_expr = match expr { + ast::Expr::FieldExpr(fe) => fe, + _ => return None, + }; + + let expr = field_expr.expr()?; + let ty = match sema.type_of_expr(&expr) { + Some(ty) => ty, + None => { + println!("No type :("); + return None; + } + }; + if !ty.is_packed(db) { + return None; + } + + // FIXME account for alignment... somehow + + Highlight::new(HighlightTag::Operator) | HighlightModifier::Unsafe + } p if p.is_punct() => match p { T![::] | T![->] | T![=>] | T![&] | T![..] | T![=] | T![@] => { HighlightTag::Operator.into() diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs index 09062c38e..f2c078d34 100644 --- a/crates/ra_ide/src/syntax_highlighting/tests.rs +++ b/crates/ra_ide/src/syntax_highlighting/tests.rs @@ -292,6 +292,13 @@ struct TypeForStaticMut { static mut global_mut: TypeForStaticMut = TypeForStaticMut { a: 0 }; +#[repr(packed)] +struct Packed { + a: u16, + b: u8, + c: u32, +} + fn main() { let x = &5 as *const usize; let u = Union { b: 0 }; @@ -306,6 +313,10 @@ fn main() { let y = *(x); let z = -x; let a = global_mut.a; + let packed = Packed { a: 0, b: 0, c: 0 }; + let a = &packed.a; + let b = &packed.b; + let c = &packed.c; } } "# -- cgit v1.2.3