-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Two bug fixes - disallow "new (int, int)()" and induce a failure if ValueTuple is not a struct. #14161
Two bug fixes - disallow "new (int, int)()" and induce a failure if ValueTuple is not a struct. #14161
Changes from 2 commits
7b5e3d3
bc1ad9d
593bddf
3f2436b
d21d9f7
732407b
3f7aac6
2b55e5e
430ffc7
f79bea9
73d4028
11355bd
3eacdfd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3181,6 +3181,12 @@ protected BoundExpression BindObjectCreationExpression(ObjectCreationExpressionS | |
{ | ||
var type = BindType(node.Type, diagnostics); | ||
|
||
if (node.Type.Kind() == SyntaxKind.TupleType) | ||
{ | ||
Error(diagnostics, ErrorCode.ERR_NewWithTupleTypeSyntax, node, type); | ||
return BadExpression(node, LookupResultKind.NotCreatable); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Considering that it might parse into something else in the future, I do not want to bind the type. #WontFix There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Binding the type might result in more diagnostics, or opposite - something that uses the expression type may actually work. And that will change once we change parsing. It seems to be better if we do not bind. #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aren't we already binding the type at line 3182? #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah. I see. I meant to move this to after the check. Somehow type binding is still there. Will fix. In reply to: 81443846 [](ancestors = 81443846) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think we shouldn't cancel the binding short, all constituent parts should be bound and preserved in the tree for SemanticModel benefits. I suggest we simply continue normally as it doesn't look like returning bad expression actually gives us much. #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. If we happened to parse it (not make a junk trivia), we may as well bind it. In reply to: 81652702 [](ancestors = 81652702) |
||
} | ||
|
||
BoundExpression boundInitializerOpt = node.Initializer == null ? | ||
null : | ||
BindInitializerExpressionOrValue( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4929,6 +4929,12 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ | |
<data name="WRN_TupleLiteralNameMismatch_Title" xml:space="preserve"> | ||
<value>The tuple element name is ignored because a different name is specified by the assignment target.</value> | ||
</data> | ||
<data name="ERR_PredefinedValueTupleTypeMustBeStruct" xml:space="preserve"> | ||
<value>Predefined type '{0}' must be a struct.</value> | ||
</data> | ||
<data name="ERR_NewWithTupleTypeSyntax" xml:space="preserve"> | ||
<value>"new" cannot be used with tuple type '{0}'. Use a tuple literal expression instead.</value> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Resource strings typically using single quotes rather than double quotes for keywords: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
</data> | ||
<data name="ERR_DeconstructionVarFormDisallowsSpecificType" xml:space="preserve"> | ||
<value>Deconstruction 'var (...)' form disallows a specific type for 'var'.</value> | ||
</data> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ internal abstract class PEModuleBuilder : PEModuleBuilder<CSharpCompilation, Sou | |
// TODO: Need to estimate amount of elements for this map and pass that value to the constructor. | ||
protected readonly ConcurrentDictionary<Symbol, Cci.IModuleReference> AssemblyOrModuleSymbolToModuleRefMap = new ConcurrentDictionary<Symbol, Cci.IModuleReference>(); | ||
private readonly ConcurrentDictionary<Symbol, object> _genericInstanceMap = new ConcurrentDictionary<Symbol, object>(); | ||
private readonly ConcurrentSet<ErrorTypeSymbol> _reportedErrorTypesMap = new ConcurrentSet<ErrorTypeSymbol>(); | ||
private readonly ConcurrentSet<TypeSymbol> _reportedErrorTypesMap = new ConcurrentSet<TypeSymbol>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this set should use an identity comparer. #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will change to identity. |
||
|
||
private readonly NoPia.EmbeddedTypesManager _embeddedTypesManagerOpt; | ||
public override NoPia.EmbeddedTypesManager EmbeddedTypesManagerOpt | ||
|
@@ -790,6 +790,19 @@ internal Cci.INamedTypeReference Translate( | |
{ | ||
Debug.Assert(!needDeclaration); | ||
namedTypeSymbol = namedTypeSymbol.TupleUnderlyingType; | ||
|
||
// check that underlying type of a ValueTuple is indeed a value type (or error) | ||
// this should never happen, in theory, | ||
// but if it does happen we should make it a failure. | ||
var declaredBase = namedTypeSymbol.BaseTypeNoUseSiteDiagnostics; | ||
if (declaredBase.SpecialType != SpecialType.System_ValueType && !declaredBase.IsErrorType()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason not to simply check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. namedTypeSymbol is not necessarily a tuple and many types would default to be classes or whatever. In reply to: 81642661 [](ancestors = 81642661) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
{ | ||
// Try to decrease noise by not complaining about the same type over and over again. | ||
if (_reportedErrorTypesMap.Add(namedTypeSymbol)) | ||
{ | ||
diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_PredefinedValueTupleTypeMustBeStruct, namedTypeSymbol.MetadataName), syntaxNodeOpt == null ? NoLocation.Singleton : syntaxNodeOpt.Location)); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider extracting this block to a method. |
||
} | ||
|
||
// Substitute error types with a special singleton object. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -663,22 +663,6 @@ internal override ImmutableArray<NamedTypeSymbol> InterfacesNoUseSiteDiagnostics | |
return _underlyingType.InterfacesNoUseSiteDiagnostics(basesBeingResolved); | ||
} | ||
|
||
public override bool IsReferenceType | ||
{ | ||
get | ||
{ | ||
return _underlyingType.IsErrorType() ? false : _underlyingType.IsReferenceType; | ||
} | ||
} | ||
|
||
public override bool IsValueType | ||
{ | ||
get | ||
{ | ||
return _underlyingType.IsErrorType() || _underlyingType.IsValueType; | ||
} | ||
} | ||
|
||
internal sealed override bool IsManagedType | ||
{ | ||
get | ||
|
@@ -1097,10 +1081,9 @@ public override TypeKind TypeKind | |
{ | ||
get | ||
{ | ||
// only classes and structs can have instance fields as tuple requires. | ||
// we need to have some support for classes, but most common case will be struct | ||
// in broken scenarios (ErrorType, Enum, Delegate, whatever..) we will just default to struct. | ||
return _underlyingType.TypeKind == TypeKind.Class ? TypeKind.Class : TypeKind.Struct; | ||
// From the language prospective tuple is a value type | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
s/prospective/perspective/ #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
// composed of its underlying elements | ||
return TypeKind.Struct; | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please move this constraint into the parser? It is likely to be specified as a syntactic constraint. The syntax
new (x, y)
is reasonably likely to be a work item in the not too distant future (#35). Having this handled in the parser would make the next person's job much easier. #ResolvedThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will try move it to parser. #Resolved