diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index 758d004098..872f5fa4c7 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -289,8 +289,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.imp.is_unsafe_ref_expr(ref_expr) } - pub fn is_unsafe_bind_pat(&self, bind_pat: &ast::BindPat) -> bool { - self.imp.is_unsafe_bind_pat(bind_pat) + pub fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool { + self.imp.is_unsafe_ident_pat(ident_pat) } } @@ -629,20 +629,24 @@ impl<'db> SemanticsImpl<'db> { // more than it should with the current implementation. } - pub fn is_unsafe_bind_pat(&self, bind_pat: &ast::BindPat) -> bool { - bind_pat + pub fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool { + if !ident_pat.ref_token().is_some() { + return false; + } + + ident_pat .syntax() .parent() .and_then(|parent| { - // `BindPat` can live under `RecordPat` directly under `RecordFieldPat` or - // `RecordFieldPatList`. `RecordFieldPat` also lives under `RecordFieldPatList`, - // so this tries to lookup the `BindPat` anywhere along that structure to the + // `IdentPat` can live under `RecordPat` directly under `RecordPatField` or + // `RecordPatFieldList`. `RecordPatField` also lives under `RecordPatFieldList`, + // so this tries to lookup the `IdentPat` anywhere along that structure to the // `RecordPat` so we can get the containing type. - let record_pat = ast::RecordFieldPat::cast(parent.clone()) + let record_pat = ast::RecordPatField::cast(parent.clone()) .and_then(|record_pat| record_pat.syntax().parent()) .or_else(|| Some(parent.clone())) .and_then(|parent| { - ast::RecordFieldPatList::cast(parent)? + ast::RecordPatFieldList::cast(parent)? .syntax() .parent() .and_then(ast::RecordPat::cast) diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 4527885e93..c62bb3f1ab 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -662,9 +662,9 @@ fn highlight_element( } T![ref] => element .parent() - .and_then(ast::BindPat::cast) - .and_then(|bind_pat| { - if sema.is_unsafe_bind_pat(&bind_pat) { + .and_then(ast::IdentPat::cast) + .and_then(|ident_pat| { + if sema.is_unsafe_ident_pat(&ident_pat) { Some(HighlightModifier::Unsafe) } else { None diff --git a/crates/ra_ide/test_data/highlight_unsafe.html b/crates/ra_ide/test_data/highlight_unsafe.html index a2df2c27e6..552fea6689 100644 --- a/crates/ra_ide/test_data/highlight_unsafe.html +++ b/crates/ra_ide/test_data/highlight_unsafe.html @@ -54,6 +54,19 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd static mut global_mut: TypeForStaticMut = TypeForStaticMut { a: 0 }; +#[repr(packed)] +struct Packed { + a: u16, +} + +trait DoTheAutoref { + fn calls_autoref(&self); +} + +impl DoTheAutoref for u16 { + fn calls_autoref(&self) {} +} + fn main() { let x = &5 as *const _ as *const usize; let u = Union { b: 0 }; @@ -66,8 +79,21 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd Union { a } => (), } HasUnsafeFn.unsafe_method(); - let y = *(x); - let z = -x; + + // unsafe deref + let y = *x; + + // unsafe access to a static mut let a = global_mut.a; + + // unsafe ref of packed fields + let packed = Packed { a: 0 }; + let a = &packed.a; + let ref a = packed.a; + let Packed { ref a } = packed; + let Packed { a: ref _a } = packed; + + // unsafe auto ref of packed field + packed.a.calls_autoref(); } } \ No newline at end of file