markdown fixes for 7.3 proposals

These were:

1. adding `csharp` as the language identifier.
1. making relative links to content published on docs.microsoft.com
1. small grammar fixes.
This commit is contained in:
Bill Wagner 2019-03-07 16:04:57 -05:00
parent 68a95404a1
commit f69b012846
8 changed files with 60 additions and 69 deletions

View file

@ -15,7 +15,7 @@ Currently it is not possible to apply attributes to the backing fields of auto-i
In short, the following would be legal C# and not produce a warning:
```cs
```csharp
[Serializable]
public class Foo
{
@ -26,7 +26,7 @@ public class Foo
This would result in the field-targeted attributes being applied to the compiler-generated backing field:
```cs
```csharp
[Serializable]
public class Foo
{
@ -43,7 +43,7 @@ public class Foo
As mentioned, this brings parity with event syntax from C# 1.0 as the following is already legal and behaves as expected:
```cs
```csharp
[Serializable]
public class Foo
{
@ -67,5 +67,3 @@ There are two potential drawbacks to implementing this change:
[unresolved]: #unresolved-questions
## Design meetings

View file

@ -10,14 +10,14 @@ The unmanaged constraint feature will give language enforcement to the class of
The primary motivation is to make it easier to author low level interop code in C#. Unmanaged types are one of the core building blocks for interop code, yet the lack of support in generics makes it impossible to create re-usable routines across all unmanaged types. Instead developers are forced to author the same boiler plate code for every unmanaged type in their library:
``` c#
```csharp
int Hash(Point point) { ... }
int Hash(TimeSpan timeSpan) { ... }
```
To enable this type of scenario the language will be introducing a new constraint: unmanaged:
``` c#
```csharp
void Hash<T>(T value) where T : unmanaged
{
...
@ -26,7 +26,7 @@ void Hash<T>(T value) where T : unmanaged
This constraint can only be met by types which fit into the unmanaged type definition in the C# language spec. Another way of looking at it is that a type satisfies the unmanaged constraint iff it can also be used as a pointer.
``` c#
```csharp
Hash(new Point()); // Okay
Hash(42); // Okay
Hash("hello") // Error: Type string does not satisfy the unmanaged constraint
@ -34,8 +34,7 @@ Hash("hello") // Error: Type string does not satisfy the unmanaged constraint
Type parameters with the unmanaged constraint can use all the features available to unmanaged types: pointers, fixed, etc ...
``` c#
```csharp
void Hash<T>(T value) where T : unmanaged
{
// Okay
@ -48,7 +47,7 @@ void Hash<T>(T value) where T : unmanaged
This constraint will also make it possible to have efficient conversions between structured data and streams of bytes. This is an operation that is common in networking stacks and serialization layers:
``` c#
```csharp
Span<byte> Convert<T>(ref T value) where T : unmanaged
{
...
@ -71,7 +70,7 @@ Compiler generated instance fields, such as those backing auto-implemented prope
For example:
``` c#
```csharp
// Unmanaged type
struct Point
{
@ -121,7 +120,7 @@ There are a couple of alternatives to consider:
The F# language encodes the constraint in the signature file which means C# cannot re-use their representation. A new attribute will need to be chosen for this constraint. Additionally a method which has this constraint must be protected by a mod-req.
### Blittable vs. Unmanaged
The F# language has a very [similar feature](https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/generics/constraints) which uses the keyword unmanaged. The blittable name comes from the use in Midori. May want to look to precedence here and use unmanaged instead.
The F# language has a very [similar feature](https://docs.microsoft.com/dotnet/articles/fsharp/language-reference/generics/constraints) which uses the keyword unmanaged. The blittable name comes from the use in Midori. May want to look to precedence here and use unmanaged instead.
**Resolution** The language decide to use unmanaged

View file

@ -1,4 +1,4 @@
# expression variables in initializers
# Expression variables in initializers
## Summary
[summary]: #summary

View file

@ -1,4 +1,3 @@
# Indexing `fixed` fields should not require pinning regardless of the movable/unmovable context. #
The change has the size of a bug fix. It can be in 7.3 and does not conflict with whatever direction we take further.
@ -6,7 +5,7 @@ This change is only about allowing the following scenario to work even though `s
NOTE: in either case, it still requires `unsafe` context. It is possible to read uninitialized data or even out of range. That is not changing.
```C#
```csharp
unsafe struct S
{
public fixed int myFixedField[10];
@ -27,7 +26,7 @@ The main “challenge” that I see here is how to explain the relaxation in the
In particular, since the following would still need pinning.
(because `s` is moveable and we explicitly use the field as a pointer)
```C#
```csharp
unsafe struct S
{
public fixed int myFixedField[10];
@ -48,5 +47,3 @@ class Program
One reason why we require pinning of the target when it is movable is the artifact of our code generation strategy, - we always convert to an unmanaged pointer and thus force the user to pin via `fixed` statement. However, conversion to unmanaged is unnecessary when doing indexing. The same unsafe pointer math is equally applicable when we have the receiver in the form of a managed pointer. If we do that, then the intermediate ref is managed (GC-tracked) and the pinning is unnecessary.
The change https://github.com/dotnet/roslyn/pull/24966 is a prototype PR that relaxes this requirement.

View file

@ -10,7 +10,7 @@ Introduce a pattern that would allow types to participate in `fixed` statements.
The language provides a mechanism for pinning managed data and obtain a native pointer to the underlying buffer.
```C#
```csharp
fixed(byte* ptr = byteArray)
{
// ptr is a native pointer to the first element of the array
@ -39,12 +39,12 @@ I think the above could be satisfied by recognizing a specially named ref-return
In order to be used by the `fixed` statement the following conditions must be met:
1) There is only one such member provided for a type.
1) Returns by `ref` or `ref readonly`.
1. There is only one such member provided for a type.
1. Returns by `ref` or `ref readonly`.
(`readonly` is permitted so that authors of immutable/readonly types could implement the pattern without adding writeable API that could be used in safe code)
1) T is an unmanaged type.
1. T is an unmanaged type.
(since `T*` becomes the pointer type. The restriction will naturally expand if/when the notion of "unmanaged" is expanded)
1) Returns managed `nullptr` when there is no data to pin probably the cheapest way to convey emptiness.
1. Returns managed `nullptr` when there is no data to pin probably the cheapest way to convey emptiness.
(note that “” string returns a ref to '\0' since strings are null-terminated)
Alternatively for the `#3` we can allow the result in empty cases be undefined or implementation-specific.
@ -52,49 +52,46 @@ That, however, may make the API more dangerous and prone to abuse and unintended
## *Translation* ##
```C#
fixed(byte* ptr = thing)
{
// <BODY>
}
```csharp
fixed(byte* ptr = thing)
{
// <BODY>
}
```
becomes the following pseudocode (not all expressible in C#)
```C#
```csharp
byte* ptr;
// specially decorated "pinned" IL local slot, not visible to user code.
pinned ref byte _pinned;
byte* ptr;
// specially decorated "pinned" IL local slot, not visible to user code.
pinned ref byte _pinned;
try
try
{
// NOTE: null check is omitted for value types
// NOTE: `thing` is evaluated only once (temporary is introduced if necessary)
if (thing != null)
{
// NOTE: null check is omitted for value types
// NOTE: `thing` is evaluated only once (temporary is introduced if necessary)
if (thing != null)
{
// obtain and "pin" the reference
_pinned = ref thing.GetPinnableReference();
// obtain and "pin" the reference
_pinned = ref thing.GetPinnableReference();
// unsafe cast in IL
ptr = (byte*)_pinned;
}
else
{
ptr = default(byte*);
}
// <BODY>
// unsafe cast in IL
ptr = (byte*)_pinned;
}
finally // finally can be omitted when not observable
else
{
// "unpin" the object
_pinned = nullptr;
ptr = default(byte*);
}
// <BODY>
}
finally // finally can be omitted when not observable
{
// "unpin" the object
_pinned = nullptr;
}
```
## Drawbacks
[drawbacks]: #drawbacks
@ -105,11 +102,11 @@ becomes the following pseudocode (not all expressible in C#)
Users can introduce GetPinnableReference or similar member and use it as
```C#
fixed(byte* ptr = thing.GetPinnableReference())
{
// <BODY>
}
```csharp
fixed(byte* ptr = thing.GetPinnableReference())
{
// <BODY>
}
```
There is no solution for `System.String` if alternative solution is desired.

View file

@ -4,7 +4,7 @@ In C# 7.3, we add support for rebinding the referent of a ref local variable or
We add the following to the set of `assignment_operator`s.
``` antlr
```antlr
assignment_operator
: '=' 'ref'
;
@ -24,4 +24,4 @@ The safety rules for this operator are:
- For a ref reassignment `e1 = ref e2`, the *ref-safe-to-escape* of `e2` must be at least as wide a scope as the *ref-safe-to-escape* of `e1`.
Where *ref-safe-to-escape* is defined in https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/span-safety.md
Where *ref-safe-to-escape* is defined in [Safety for ref-like types](../csharp-7.2/span-safety.md)

View file

@ -1,9 +1,9 @@
# Stackalloc array initializers.
# Stackalloc array initializers
## Summary
[summary]: #summary
Allow array initializer syntax to be used with `stackalloc`
Allow array initializer syntax to be used with `stackalloc`.
## Motivation
[motivation]: #motivation
@ -11,13 +11,13 @@ Allow array initializer syntax to be used with `stackalloc`
Ordinary arrays can have their elements initialized at creation time. It seems reasonable to allow that in `stackalloc` case.
The question of why such syntax is not allowed with `stackalloc` arises fairly frequently.
See, for example, https://github.com/dotnet/csharplang/issues/1112
See, for example, [#1112](https://github.com/dotnet/csharplang/issues/1112)
## Detailed design
Ordinary arrays can be created through the following syntax:
```C#
```csharp
new int[3]
new int[3] { 1, 2, 3 }
new int[] { 1, 2, 3 }
@ -26,7 +26,7 @@ new[] { 1, 2, 3 }
We should allow stack allocated arrays be created through:
```C#
```csharp
stackalloc int[3] // currently allowed
stackalloc int[3] { 1, 2, 3 }
stackalloc int[] { 1, 2, 3 }
@ -38,7 +38,7 @@ For example: in the last case the element type is inferred from the initializer
NOTE: the feature is not dependent on the target being a `Span<T>`. It is just as applicable in `T*` case, so it does not seem reasonable to predicate it on `Span<T>` case.
## Translation ##
## Translation
The naive implementation could just initialize the array right after creation through a series of element-wise assignments.

View file

@ -73,5 +73,5 @@ If someone wrote their own `ValueTuple` types with an implementation of the com
----
Relates to https://github.com/dotnet/csharplang/blob/master/spec/expressions.md#relational-and-type-testing-operators
Relates to https://github.com/dotnet/csharplang/issues/190
Relates to [relational and type testing operators](../../spec/expressions.md#relational-and-type-testing-operators)
Relates to [#190](https://github.com/dotnet/csharplang/issues/190)