Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions proposals/unsafe-evolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,16 @@ value cannot be safely called by C#, as the calling convention used for the meth

Today, as covered by the [unsafe context specification][unsafe-context-spec], `unsafe` behaves in a lexical manner, marking the entire textual body contained by the `unsafe` block as an `unsafe` context
(except for iterator bodies). We propose changing this definition from textual to sematic. `unsafe` on a member will mean that that member is `unsafe`, and the body of that member is considered an `unsafe`
context. `unsafe` on a type (other than delegate types) will be permitted for source compatibility purposes only; it will have no meaning, and the compiler will produce a warning informing the user that it
does not have any effect.
context.

`unsafe` on the following declarations will be permitted for source compatibility purposes only; it will have no meaning, and the compiler will produce a warning informing the user that it does not have any effect:
- type (except delegate type),
- `using static`,
- `using` alias.

Note that `unsafe` on the following declarations will not have any effect on the callers but it will have an effect on the body/initializer of the member:
- field (there is [an open question](#unsafe-fields) for this),
- destructor.

`unsafe` on a member is _not_ applied to any nested anonymous or local functions inside the member. To mark a anonymous or local function as `unsafe`, it must manually be marked as `unsafe`. The same goes for
anonymous and local functions declared inside of an `unsafe` block.
Expand All @@ -180,7 +188,9 @@ partial class C1
}
```

For properties, `get` and `set/init` members can be independently declared as `unsafe`; marking the entire property as `unsafe` means that both the `get` and `set/init` members are unsafe.
For properties, `get` and `set/init` accessors can be independently declared as `unsafe`; marking the entire property as `unsafe` means that both the `get` and `set/init` accessors are unsafe.
It is currently not possible to place any modifiers on event accessors, and this proposal doesn't change that, i.e., `add` and `remove` event accessors cannot be independently declared as `unsafe`.
Only if the entire event is marked as `unsafe`, it means that the accessors are unsafe; otherwise they are safe.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Did you also want to capture question about allowing unsafe modifier on lambdas?


#### Metadata

Expand Down Expand Up @@ -238,11 +248,15 @@ We could remove the ability to make delegate types as `unsafe` entirely, and sim
This could simplify the model around `unsafe` in C#, but at the risk of forcing `unsafe` annotations in the wrong spot and having an area where the real area of `unsafe`ty isn't properly called out. There
are a lot of corner cases here, particularly involving generics and conversions, so it may be better to simply leave the concept for later when we determine it's needed.

> [!NOTE] If we decide to disallow `unsafe` delegates, we need to add them to the list of declarations that warn for meaningless `unsafe`.

### Lambda/method group natural types

Today, the only real impact on semantics and codegen (besides additional metadata) is changing the *function_type* of a lambda or method group when `unsafe` is in the signature. If we were to avoid doing this, then
there would be no real impact to either, which could give adopters more confidence that behavior has not subtly changed under the hood.

> [!NOTE] If we decide to keep the ability to have `unsafe` lambdas, we need to update this proposal to include a syntax change to allow lambdas to be declared `unsafe` in the first place.

### `stackalloc` as initialized

Today, [the spec](https://github.com/dotnet/csharpstandard/blob/draft-v9/standard/expressions.md#12822-stack-allocation) always considers `stackalloc` memory as uninitialized, and says that the contents
Expand Down