Check val escape for initializers of fields with ref-like type#60577
Check val escape for initializers of fields with ref-like type#60577jcouv merged 5 commits intodotnet:release/dev17.2from
Conversation
| if (!boundInitializer.Value.HasAnyErrors) | ||
| { | ||
| var field = boundInitializer.Field; | ||
| if (field.Type.IsRefLikeType) |
There was a problem hiding this comment.
It wasn't clear to me whether we should check field.Type.IsRefLikeType or field.ContainingType.IsRefLikeType or both.
There was a problem hiding this comment.
I think bad ref escapes can only occur into field when field.Type.IsRefLikeType (until we add ref fields at least.)
Maybe a scenario like field = M(ref staticField) where M returns Span would be worth testing. (though I guess the safe-to-escape of a static field is global? I can't seem to think of a scenario that should cause an error here besides stackalloc. Possibly some weird scenario involving pattern variables within the initializer.)
There was a problem hiding this comment.
As you mentioned, the safe-to-escape of a static field is global.
I've added an item to the ref fields test plan to consider ref struct field initializers when ref fields is supported.
| var field = boundInitializer.Field; | ||
| if (field.Type.IsRefLikeType) | ||
| { | ||
| var value = parentBinder.ValidateEscape(boundInitializer.Value, ExternalScope, isByRef: false, diagnostics); |
There was a problem hiding this comment.
IsRefLikeType fields cannot be declared in a script since the containing type is not a ref struct. Added a test.
| var field = boundInitializer.Field; | ||
| if (field.Type.IsRefLikeType) | ||
| { | ||
| var value = parentBinder.ValidateEscape(boundInitializer.Value, ExternalScope, isByRef: false, diagnostics); |
Fixes #60568
See AB#1520561