Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge features/ref-fields #62155

Merged
merged 11 commits into from
Jun 27, 2022
Merged
65 changes: 65 additions & 0 deletions docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,71 @@ Note: The break will also apply to C# 10 and earlier when .NET 7 ships, but is
currently scoped down to users of LangVer=preview.
Tracked by https://github.com/dotnet/roslyn/issues/60640

## Cannot return an out parameter by reference

***Introduced in .NET SDK 7.0.100, Visual Studio 2022 version 17.3.***

With language version C# 11 or later, or with .NET 7.0 or later, an `out` parameter cannot be returned by reference.

```csharp
static ref T ReturnOutParamByRef<T>(out T t)
{
t = default;
return ref t; // error CS8166: Cannot return a parameter by reference 't' because it is not a ref parameter
}
```

A possible workaround is to change the method signature to pass the parameter by `ref` instead.

```csharp
static ref T ReturnRefParamByRef<T>(ref T t)
{
t = default;
return ref t; // ok
}
```

## Method ref struct return escape analysis depends on ref escape of ref arguments

***Introduced in .NET SDK 7.0.100, Visual Studio 2022 version 17.3.***

With language version C# 11 or later, or with .NET 7.0 or later, the return value of a method invocation that returns a `ref struct` is only _safe-to-escape_ if all the `ref` and `in` arguments to the method invocation are _ref-safe-to-escape_. _The `in` arguments may include implicit default parameter values._

```csharp
ref struct R { }

static R MayCaptureArg(ref int i) => new R();

static R MayCaptureDefaultArg(in int i = 0) => new R();

static R Create()
{
int i = 0;
// error CS8347: Cannot use a result of 'MayCaptureArg(ref int)' because it may expose
// variables referenced by parameter 'i' outside of their declaration scope
return MayCaptureArg(ref i);
}

static R CreateDefault()
{
// error CS8347: Cannot use a result of 'MayCaptureDefaultArg(in int)' because it may expose
// variables referenced by parameter 'i' outside of their declaration scope
return MayCaptureDefaultArg();
}
```

A possible workaround, if the `ref` or `in` argument is not captured in the `ref struct` return value, is to declare the parameter as `scoped ref` or `scoped in`.

```csharp
static R CannotCaptureArg(scoped ref int i) => new R();

static R Create()
{
int i = 0;
return CannotCaptureArg(ref i); // ok
}
```

## Unsigned right shift operator

***Introduced in .NET SDK 6.0.400, Visual Studio 2022 version 17.3.***
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public override bool HasExplicitReturnType(out RefKind refKind, out TypeWithAnno
public override bool IsAsync { get { return false; } }
public override bool IsStatic => false;
public override RefKind RefKind(int index) { return Microsoft.CodeAnalysis.RefKind.None; }
public override DeclarationScope Scope(int index) => DeclarationScope.Unscoped;
public override MessageID MessageID { get { return MessageID.IDS_FeatureQueryExpression; } } // TODO: what is the correct ID here?
public override Location ParameterLocation(int index) { return _parameters[index].Locations[0]; }
public override TypeWithAnnotations ParameterTypeWithAnnotations(int index) { throw new ArgumentException(); } // implicitly typed
Expand Down
Loading