File tree Expand file tree Collapse file tree 3 files changed +59
-1
lines changed
ide/src/syntax_highlighting/test_data
ide-diagnostics/src/handlers 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> {
296
296
297
297
return ;
298
298
}
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
+ }
299
322
_ => ( ) ,
300
323
}
301
324
}
Original file line number Diff line number Diff line change @@ -834,6 +834,41 @@ fn bar(mut v: Union2) {
834
834
)
835
835
}
836
836
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
+
837
872
#[ test]
838
873
fn raw_ref_reborrow_is_safe ( ) {
839
874
check_diagnostics (
Original file line number Diff line number Diff line change 96
96
97
97
< span class ="variable "> u</ span > < span class ="operator "> .</ span > < span class ="field unsafe "> field</ span > < span class ="semicolon "> ;</ span >
98
98
< 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 >
100
100
< span class ="comment "> // this should be safe!</ span >
101
101
< 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 >
102
102
< span class ="comment "> // but not these</ span >
You can’t perform that action at this time.
0 commit comments