File tree Expand file tree Collapse file tree 3 files changed +59
-1
lines changed
ide-diagnostics/src/handlers
ide/src/syntax_highlighting/test_data Expand file tree Collapse file tree 3 files changed +59
-1
lines changed Original file line number Diff line number Diff line change @@ -296,6 +296,29 @@ impl<'db> UnsafeVisitor<'db> {
296296
297297 return ;
298298 }
299+ Expr :: Field { .. } => {
300+ if matches ! (
301+ self . infer. field_resolution( * expr) ,
302+ Some ( Either :: Left ( FieldId { parent: VariantId :: UnionId ( _) , .. } ) )
303+ ) {
304+ match & self . body . exprs [ * expr] {
305+ Expr :: Field { expr, .. } => {
306+ // Visit the base expression (e.g., `self` in `self.field`) for safety,
307+ // but don't trigger the union field access error since we're just
308+ // creating a raw pointer, not actually reading the field
309+ self . walk_expr ( * expr) ;
310+ }
311+ _ => {
312+ self . body . walk_child_exprs_without_pats ( * expr, |child| {
313+ // If it's not a field access for some reason, fall back to normal walking
314+ // This shouldn't happen based on how this function is called
315+ self . walk_expr ( child)
316+ } ) ;
317+ }
318+ }
319+ return ;
320+ }
321+ }
299322 _ => ( ) ,
300323 }
301324 }
Original file line number Diff line number Diff line change @@ -834,6 +834,41 @@ fn bar(mut v: Union2) {
834834 )
835835 }
836836
837+ #[ test]
838+ fn raw_deref_on_union_field ( ) {
839+ check_diagnostics (
840+ r#"
841+ fn main() {
842+ union U1 {
843+ a: u8
844+ }
845+ let x = U1 { a: 3 };
846+
847+ let a = x.a;
848+ // ^^^ 💡 error: access to union field is unsafe and requires an unsafe function or block
849+
850+
851+ let b = &raw const x.a;
852+
853+ let tmp = Vec::from([1, 2, 3]);
854+
855+ let c = &raw const tmp[x.a];
856+ // ^^^ 💡 error: access to union field is unsafe and requires an unsafe function or block
857+
858+ union URef {
859+ p: &'static mut i32,
860+ }
861+
862+ fn deref_union_field(u: URef) {
863+ // Not an assignment but an access to the union field!
864+ *(u.p) = 13;
865+ // ^^^ 💡 error: access to union field is unsafe and requires an unsafe function or block
866+ }
867+ }
868+ "# ,
869+ )
870+ }
871+
837872 #[ test]
838873 fn raw_ref_reborrow_is_safe ( ) {
839874 check_diagnostics (
Original file line number Diff line number Diff line change 9696
9797 < span class ="variable "> u</ span > < span class ="operator "> .</ span > < span class ="field unsafe "> field</ span > < span class ="semicolon "> ;</ span >
9898 < span class ="operator "> &</ span > < span class ="variable "> u</ span > < span class ="operator "> .</ span > < span class ="field unsafe "> field</ span > < span class ="semicolon "> ;</ span >
99- < span class ="operator "> &</ span > < span class ="keyword "> raw</ span > < span class ="keyword const "> const</ span > < span class ="variable "> u</ span > < span class ="operator "> .</ span > < span class ="field unsafe "> field</ span > < span class ="semicolon "> ;</ span >
99+ < span class ="operator "> &</ span > < span class ="keyword "> raw</ span > < span class ="keyword const "> const</ span > < span class ="variable "> u</ span > < span class ="operator "> .</ span > < span class ="field "> field</ span > < span class ="semicolon "> ;</ span >
100100 < span class ="comment "> // this should be safe!</ span >
101101 < span class ="keyword "> let</ span > < span class ="union "> Union</ span > < span class ="brace "> {</ span > < span class ="field "> field</ span > < span class ="colon "> :</ span > < span class ="punctuation "> _</ span > < span class ="brace "> }</ span > < span class ="semicolon "> ;</ span >
102102 < span class ="comment "> // but not these</ span >
You can’t perform that action at this time.
0 commit comments