@@ -297,25 +297,9 @@ impl<'db> UnsafeVisitor<'db> {
297
297
return ;
298
298
}
299
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
- }
300
+ if self . contains_union_field_access ( * expr) {
301
+ // Walk the entire field access chain without triggering union field errors
302
+ self . walk_field_chain_for_raw_ptr ( * expr) ;
319
303
return ;
320
304
}
321
305
}
@@ -424,4 +408,43 @@ impl<'db> UnsafeVisitor<'db> {
424
408
}
425
409
}
426
410
}
411
+
412
+ fn contains_union_field_access ( & mut self , expr : ExprId ) -> bool {
413
+ match & self . body . exprs [ expr] {
414
+ Expr :: Field { expr : base_expr, .. } => {
415
+ // Check if this field access is from a union
416
+ if matches ! (
417
+ self . infer. field_resolution( expr) ,
418
+ Some ( Either :: Left ( FieldId { parent: VariantId :: UnionId ( _) , .. } ) )
419
+ ) {
420
+ true
421
+ } else {
422
+ // Recursively check the base expression
423
+ self . contains_union_field_access ( * base_expr)
424
+ }
425
+ }
426
+ _ => false ,
427
+ }
428
+ }
429
+
430
+ /// Walks a field access chain for raw pointer creation, avoiding union field access errors
431
+ fn walk_field_chain_for_raw_ptr ( & mut self , expr : ExprId ) {
432
+ match & self . body . exprs [ expr] {
433
+ Expr :: Field { expr : base_expr, .. } => {
434
+ // First, recursively handle the base expression
435
+ self . walk_field_chain_for_raw_ptr ( * base_expr) ;
436
+
437
+ // Then handle any non-field child expressions of this field access
438
+ self . body . walk_child_exprs_without_pats ( expr, |child| {
439
+ if child != * base_expr {
440
+ self . walk_expr ( child) ;
441
+ }
442
+ } ) ;
443
+ }
444
+ _ => {
445
+ // We've reached the base expression (not a field access), walk it normally
446
+ self . walk_expr ( expr) ;
447
+ }
448
+ }
449
+ }
427
450
}
0 commit comments