Skip to content

Commit

Permalink
Report diagnostics for inline array types that are not valid as type …
Browse files Browse the repository at this point in the history
…arguments.

Fixes dotnet#71058.
  • Loading branch information
AlekseyTs committed Dec 5, 2023
1 parent 23e0905 commit d6369d7
Show file tree
Hide file tree
Showing 19 changed files with 186 additions and 86 deletions.
20 changes: 17 additions & 3 deletions src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -438,15 +438,23 @@ void checkConstraintLanguageVersionAndRuntimeSupportForConversion(SyntaxNode syn
}

CheckFeatureAvailability(syntax, MessageID.IDS_FeatureInlineArrays, diagnostics);
diagnostics.ReportUseSite(source.Type!.TryGetInlineArrayElementField(), syntax);

Debug.Assert(source.Type is { });

FieldSymbol? elementField = source.Type.TryGetInlineArrayElementField();
Debug.Assert(elementField is { });

diagnostics.ReportUseSite(elementField, syntax);

Symbol? unsafeAsMethod = null;

if (destination.OriginalDefinition.Equals(Compilation.GetWellKnownType(WellKnownType.System_ReadOnlySpan_T), TypeCompareKind.AllIgnoreOptions))
{
if (CheckValueKind(syntax, source, BindValueKind.RefersToLocation, checkingReceiver: false, BindingDiagnosticBag.Discarded))
{
_ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_InteropServices_MemoryMarshal__CreateReadOnlySpan, diagnostics, syntax: syntax); // This also takes care of an 'int' type
_ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__AsRef_T, diagnostics, syntax: syntax);
_ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: syntax);
unsafeAsMethod = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: syntax);
}
else
{
Expand All @@ -460,13 +468,19 @@ void checkConstraintLanguageVersionAndRuntimeSupportForConversion(SyntaxNode syn
if (CheckValueKind(syntax, source, BindValueKind.RefersToLocation | BindValueKind.Assignable, checkingReceiver: false, BindingDiagnosticBag.Discarded))
{
_ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_InteropServices_MemoryMarshal__CreateSpan, diagnostics, syntax: syntax); // This also takes care of an 'int' type
_ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: syntax);
unsafeAsMethod = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: syntax);
}
else
{
Error(diagnostics, ErrorCode.ERR_InlineArrayConversionToSpanNotSupported, syntax, destination);
}
}

if (unsafeAsMethod is MethodSymbol { HasUnsupportedMetadata: false } method)
{
method.Construct(ImmutableArray.Create(TypeWithAnnotations.Create(source.Type), elementField.TypeWithAnnotations)).
CheckConstraints(new ConstraintsHelper.CheckConstraintsArgs(this.Compilation, this.Conversions, syntax.GetLocation(), diagnostics));
}
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8514,13 +8514,14 @@ BoundExpression bindInlineArrayElementAccess(ExpressionSyntax node, BoundExpress
}
}

_ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: node);
var unsafeAsMethod = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: node);
_ = GetWellKnownTypeMember(createSpanHelper, diagnostics, syntax: node);
var spanMethod = GetWellKnownTypeMember(getItemOrSliceHelper, diagnostics, syntax: node);
_ = GetWellKnownTypeMember(getItemOrSliceHelper, diagnostics, syntax: node);

if (spanMethod is { ContainingType: { Kind: SymbolKind.NamedType } spanType })
if (unsafeAsMethod is MethodSymbol { HasUnsupportedMetadata: false } method)
{
spanType.Construct(ImmutableArray.Create(elementField.TypeWithAnnotations)).CheckConstraints(new ConstraintsHelper.CheckConstraintsArgs(this.Compilation, this.Conversions, node.GetLocation(), diagnostics));
method.Construct(ImmutableArray.Create(TypeWithAnnotations.Create(expr.Type), elementField.TypeWithAnnotations)).
CheckConstraints(new ConstraintsHelper.CheckConstraintsArgs(this.Compilation, this.Conversions, node.GetLocation(), diagnostics));
}

if (!Compilation.Assembly.RuntimeSupportsInlineArrayTypes)
Expand Down
9 changes: 7 additions & 2 deletions src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,6 @@ private EnumeratorResult GetEnumeratorInfoCore(SyntaxNode syntax, ExpressionSynt
}

spanType = spanType.Construct(ImmutableArray.Create(elementField.TypeWithAnnotations));
spanType.CheckConstraints(new ConstraintsHelper.CheckConstraintsArgs(this.Compilation, this.Conversions, collectionExpr.Syntax.GetLocation(), diagnostics));

if (!TypeSymbol.IsInlineArrayElementFieldSupported(elementField))
{
Expand Down Expand Up @@ -883,7 +882,13 @@ private EnumeratorResult GetEnumeratorInfoCore(SyntaxNode syntax, ExpressionSynt
}

_ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__Add_T, diagnostics, syntax: collectionExpr.Syntax);
_ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: collectionExpr.Syntax);
var unsafeAsMethod = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: collectionExpr.Syntax);

if (unsafeAsMethod is MethodSymbol { HasUnsupportedMetadata: false } method)
{
method.Construct(ImmutableArray.Create(TypeWithAnnotations.Create(collectionExpr.Type), elementField.TypeWithAnnotations)).
CheckConstraints(new ConstraintsHelper.CheckConstraintsArgs(this.Compilation, this.Conversions, collectionExpr.Syntax.GetLocation(), diagnostics));
}
}

return result;
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/CSharpResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -7774,10 +7774,10 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<value>Inline array conversion operator will not be used for conversion from expression of the declaring type.</value>
</data>
<data name="WRN_InlineArrayNotSupportedByLanguage" xml:space="preserve">
<value>'Inline arrays' language feature is not supported for inline array types with element field which is either a 'ref' field, or has type that is not valid as a type argument.</value>
<value>'Inline arrays' language feature is not supported for an inline array type that is not valid as a type argument, or has element type that is not valid as a type argument.</value>
</data>
<data name="WRN_InlineArrayNotSupportedByLanguage_Title" xml:space="preserve">
<value>'Inline arrays' language feature is not supported for inline array types with element field which is either a 'ref' field, or has type that is not valid as a type argument.</value>
<value>'Inline arrays' language feature is not supported for an inline array type that is not valid as a type argument, or has element type that is not valid as a type argument.</value>
</data>
<data name="ERR_InlineArrayForEachNotSupported" xml:space="preserve">
<value>foreach statement on an inline array of type '{0}' is not supported</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1876,10 +1876,16 @@ protected override void AfterMembersCompletedChecks(BindingDiagnosticBag diagnos
}
}

if (!reported_ERR_InlineArrayUnsupportedElementFieldModifier &&
(!fieldSupported || elementType.Type.IsPointerOrFunctionPointer() || elementType.IsRestrictedType()))
if (!reported_ERR_InlineArrayUnsupportedElementFieldModifier)
{
diagnostics.Add(ErrorCode.WRN_InlineArrayNotSupportedByLanguage, elementField.TryGetFirstLocation() ?? GetFirstLocation());
if (!fieldSupported || elementType.Type.IsPointerOrFunctionPointer() || elementType.IsRestrictedType())
{
diagnostics.Add(ErrorCode.WRN_InlineArrayNotSupportedByLanguage, elementField.TryGetFirstLocation() ?? GetFirstLocation());
}
else if (this.IsRestrictedType())
{
diagnostics.Add(ErrorCode.WRN_InlineArrayNotSupportedByLanguage, GetFirstLocation());
}
}
}
else
Expand Down
8 changes: 4 additions & 4 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit d6369d7

Please sign in to comment.