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

Address additional PROTOTYPE comments for native integers #42419

Merged
merged 15 commits into from
Mar 19, 2020
3 changes: 2 additions & 1 deletion src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1248,10 +1248,11 @@ private UnaryOperatorAnalysisResult UnaryOperatorOverloadResolution(
// the unary minus operator could be applied to the result. But though float is better than double,
// float is neither better nor worse than decimal. However it seems odd to give an ambiguity error
// when trying to do something such as applying a unary minus operator to an unsigned long.
// The same issue applies to unary minus applied to nuint.

if (kind == UnaryOperatorKind.UnaryMinus &&
(object)operand.Type != null &&
operand.Type.SpecialType == SpecialType.System_UInt64)
(operand.Type.SpecialType == SpecialType.System_UInt64 || (operand.Type.SpecialType == SpecialType.System_UIntPtr && operand.Type.IsNativeIntegerType)))
{
resultKind = LookupResultKind.OverloadResolutionFailure;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,6 @@ private BoundExpression RewriteLiftedConversionInExpressionTree(
typeToUnderlying = typeTo.GetEnumUnderlyingType();
}

// PROTOTYPE: Test conversions to/from native int.
var method = (MethodSymbol)_compilation.Assembly.GetSpecialTypeMember(DecimalConversionMethod(typeFromUnderlying, typeToUnderlying));
var conversionKind = conversion.Kind.IsImplicitConversion() ? ConversionKind.ImplicitUserDefined : ConversionKind.ExplicitUserDefined;
var result = new BoundConversion(syntax, rewrittenOperand, new Conversion(conversionKind, method, false), @checked, explicitCastInCode: explicitCastInCode, conversionGroup, default(ConstantValue), rewrittenType);
Expand Down Expand Up @@ -1310,6 +1309,7 @@ public static SpecialMember GetIntPtrConversionMethod(TypeSymbol source, TypeSym
throw ExceptionUtilities.Unreachable;
}

// https://github.com/dotnet/roslyn/issues/42452: Test with native integers and expression trees.
private static SpecialMember DecimalConversionMethod(TypeSymbol typeFrom, TypeSymbol typeTo)
{
if (typeFrom.SpecialType == SpecialType.System_Decimal)
Expand Down Expand Up @@ -1393,7 +1393,6 @@ private BoundExpression RewriteDecimalConversionCore(SyntaxNode syntax, BoundExp

if (_inExpressionLambda)
{
// PROTOTYPE: Test expression lambda cases converting between native ints and decimal.
ConversionKind conversionKind = isImplicit ? ConversionKind.ImplicitUserDefined : ConversionKind.ExplicitUserDefined;
var conversion = new Conversion(conversionKind, method, isExtensionMethod: false);

Expand Down Expand Up @@ -1457,7 +1456,6 @@ private Conversion TryMakeConversion(SyntaxNode syntax, Conversion conversion, T
// TODO: what about nullable?
if (fromType.SpecialType == SpecialType.System_Decimal || toType.SpecialType == SpecialType.System_Decimal)
{
// PROTOTYPE: Test conversions to/from native int.
SpecialMember member = DecimalConversionMethod(fromType, toType);
MethodSymbol method;
if (!TryGetSpecialTypeMethod(syntax, member, out method))
Expand All @@ -1473,7 +1471,6 @@ private Conversion TryMakeConversion(SyntaxNode syntax, Conversion conversion, T
// TODO: what about nullable?
if (fromType.SpecialType == SpecialType.System_Decimal)
{
// PROTOTYPE: Test conversions to/from native int.
SpecialMember member = DecimalConversionMethod(fromType, toType.GetEnumUnderlyingType());
MethodSymbol method;
if (!TryGetSpecialTypeMethod(syntax, member, out method))
Expand All @@ -1485,7 +1482,6 @@ private Conversion TryMakeConversion(SyntaxNode syntax, Conversion conversion, T
}
else if (toType.SpecialType == SpecialType.System_Decimal)
{
// PROTOTYPE: Test conversions to/from native int.
SpecialMember member = DecimalConversionMethod(fromType.GetEnumUnderlyingType(), toType);
MethodSymbol method;
if (!TryGetSpecialTypeMethod(syntax, member, out method))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,10 @@ internal override ImmutableArray<NamedTypeSymbol> GetDeclaredInterfaces(ConsList
return ImmutableArray<NamedTypeSymbol>.Empty;
}

internal sealed override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable;

internal sealed override NamedTypeSymbol NativeIntegerUnderlyingType => null;

internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison, IReadOnlyDictionary<TypeParameterSymbol, bool> isValueTypeOverrideOpt = null)
{
Debug.Assert(isValueTypeOverrideOpt == null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,10 @@ internal override AttributeUsageInfo GetAttributeUsageInfo()
return AttributeUsageInfo.Null;
}

internal sealed override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable;

internal sealed override NamedTypeSymbol NativeIntegerUnderlyingType => null;

internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder<SynthesizedAttributeData> attributes)
{
base.AddSynthesizedAttributes(moduleBuilder, ref attributes);
Expand Down
5 changes: 4 additions & 1 deletion src/Compilers/CSharp/Portable/Symbols/ErrorTypeSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#nullable enable

using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -532,6 +531,10 @@ public sealed override bool AreLocalsZeroed
get { throw ExceptionUtilities.Unreachable; }
}

internal override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable;

internal override NamedTypeSymbol? NativeIntegerUnderlyingType => null;

protected sealed override ISymbol CreateISymbol()
{
return new PublicModel.ErrorTypeSymbol(this, DefaultNullableAnnotation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.CSharp.Symbols
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2332,6 +2332,8 @@ internal override NamedTypeSymbol AsNativeInteger()
return ContainingAssembly.GetNativeIntegerType(this);
}

internal override NamedTypeSymbol NativeIntegerUnderlyingType => null;

internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison, IReadOnlyDictionary<TypeParameterSymbol, bool> isValueTypeOverrideOpt = null)
{
return t2 is NativeIntegerTypeSymbol nativeInteger ?
Expand Down Expand Up @@ -2418,6 +2420,10 @@ public override ImmutableArray<TypeParameterSymbol> TypeParameters
}
}

internal sealed override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable;

internal sealed override NamedTypeSymbol NativeIntegerUnderlyingType => null;

private void EnsureTypeParametersAreLoaded()
{
if (_lazyTypeParameters.IsDefault)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ public override int GetHashCode()
return Hash.Combine(MetadataName, Hash.Combine(_containingModule, Hash.Combine(_namespaceName, arity)));
}

internal override NamedTypeSymbol AsNativeInteger() => AsNativeInteger(asNativeInt: true);
internal sealed override NamedTypeSymbol AsNativeInteger() => AsNativeInteger(asNativeInt: true);

private TopLevel AsNativeInteger(bool asNativeInt)
{
Expand All @@ -342,9 +342,9 @@ private TopLevel AsNativeInteger(bool asNativeInt)
return other;
}

internal override bool IsNativeIntegerType => _isNativeInt;
internal sealed override bool IsNativeIntegerType => _isNativeInt;

internal override NamedTypeSymbol? NativeIntegerUnderlyingType => _isNativeInt ? AsNativeInteger(asNativeInt: false) : null;
internal sealed override NamedTypeSymbol? NativeIntegerUnderlyingType => _isNativeInt ? AsNativeInteger(asNativeInt: false) : null;

internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison, IReadOnlyDictionary<TypeParameterSymbol, bool>? isValueTypeOverrideOpt = null)
{
Expand Down
6 changes: 2 additions & 4 deletions src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1509,21 +1509,19 @@ internal bool IsTupleTypeOfCardinality(out int tupleCardinality)
return false;
}

// PROTOTYPE: Should be abstract.
/// <summary>
/// Returns an instance of a symbol that represents an native integer
/// if this underlying symbol represents System.IntPtr or System.UIntPtr.
/// For other symbols, throws <see cref="System.InvalidOperationException"/>.
/// </summary>
internal virtual NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable;
internal abstract NamedTypeSymbol AsNativeInteger();

// PROTOTYPE: Should be abstract.
/// <summary>
/// If this is a native integer, returns the symbol for the underlying type,
/// either <see cref="System.IntPtr"/> or <see cref="System.UIntPtr"/>.
/// Otherwise, returns null.
/// </summary>
internal virtual NamedTypeSymbol NativeIntegerUnderlyingType => null;
internal abstract NamedTypeSymbol NativeIntegerUnderlyingType { get; }

protected override ISymbol CreateISymbol()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
// PROTOTYPE: Handle retargeting these types.
internal sealed class NativeIntegerTypeSymbol : WrappedNamedTypeSymbol, Cci.IReference
{
private ImmutableArray<NamedTypeSymbol> _lazyInterfaces;
Expand Down Expand Up @@ -90,7 +89,9 @@ internal NativeIntegerTypeSymbol(NamedTypeSymbol underlyingType) : base(underlyi

internal override bool IsNativeIntegerType => true;

internal override NamedTypeSymbol NativeIntegerUnderlyingType => _underlyingType;
internal sealed override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable;

internal sealed override NamedTypeSymbol NativeIntegerUnderlyingType => _underlyingType;

internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison, IReadOnlyDictionary<TypeParameterSymbol, bool>? isValueTypeOverrideOpt = null) => _underlyingType.Equals(t2, comparison, isValueTypeOverrideOpt);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,5 +369,9 @@ public sealed override bool AreLocalsZeroed
{
get { throw ExceptionUtilities.Unreachable; }
}

internal sealed override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable;

internal sealed override NamedTypeSymbol NativeIntegerUnderlyingType => null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ private NamedTypeSymbol RetargetNamedTypeDefinition(NamedTypeSymbol type, Retarg
{
Debug.Assert(type.IsDefinition);

if (type.IsNativeIntegerType)
{
var result = RetargetNamedTypeDefinition(type.NativeIntegerUnderlyingType, options);
return result.SpecialType == SpecialType.None ? result : result.AsNativeInteger();
}
Copy link
Contributor

@AlekseyTs AlekseyTs Mar 16, 2020

Choose a reason for hiding this comment

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

return RetargetNamedTypeDefinition(type.NativeIntegerUnderlyingType, options).AsNativeInteger();? #Closed


// Before we do anything else, check if we need to do special retargeting
// for primitive type references encoded with enum values in metadata signatures.
if (options == RetargetOptions.RetargetPrimitiveTypesByTypeCode)
Expand Down Expand Up @@ -789,8 +795,6 @@ public ImmutableArray<TypeWithAnnotations> Retarget(ImmutableArray<TypeWithAnnot

foreach (var ts in sequence)
{
// In incorrect code, a type parameter constraint list can contain primitive types.
Debug.Assert(ts.TypeKind == TypeKind.Error || ts.PrimitiveTypeCode == Cci.PrimitiveTypeCode.NotPrimitive);
result.Add(Retarget(ts, RetargetOptions.RetargetPrimitiveTypesByName));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSy
// NOTE: ref is irrelevant here since we are just encoding/decoding the type out of the signature context
ImmutableArray<bool> flags = CSharpCompilation.DynamicTransformsEncoder.EncodeWithoutCustomModifierFlags(destinationType, refKind);
TypeSymbol typeWithDynamic = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(sourceType, containingAssembly, refKind, flags);
// PROTOTYPE: Should we use NativeIntegerTypeDecoder here?
Copy link
Contributor

@AlekseyTs AlekseyTs Mar 16, 2020

Choose a reason for hiding this comment

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

// PROTOTYPE: Should we use NativeIntegerTypeDecoder here? [](start = 12, length = 58)

It is not clear why this comment is removed. It doesn't look like the encoder is called, but I think it should be called #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

#42500


In reply to: 393306528 [](ancestors = 393306528)


TypeSymbol resultType;
if (destinationType.ContainsTuple() && !sourceType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.IgnoreNullableModifiersForReferenceTypes | TypeCompareKind.IgnoreDynamic))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,9 @@ internal override ObsoleteAttributeData ObsoleteAttributeData
}

internal override bool HasCodeAnalysisEmbeddedAttribute => false;

internal sealed override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable;

internal sealed override NamedTypeSymbol NativeIntegerUnderlyingType => null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1369,6 +1369,8 @@ internal override NamedTypeSymbol AsNativeInteger()
return ContainingAssembly.GetNativeIntegerType(this);
}

internal override NamedTypeSymbol NativeIntegerUnderlyingType => null;

internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison, IReadOnlyDictionary<TypeParameterSymbol, bool> isValueTypeOverrideOpt = null)
{
return t2 is NativeIntegerTypeSymbol nativeInteger ?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,10 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.CSharp.Symbols
Expand Down Expand Up @@ -396,5 +391,9 @@ internal override IEnumerable<CSharpAttributeData> GetCustomAttributesToEmit(PEM
{
throw ExceptionUtilities.Unreachable;
}

internal sealed override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable;

internal sealed override NamedTypeSymbol NativeIntegerUnderlyingType => null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -215,5 +215,9 @@ internal override IEnumerable<FieldSymbol> GetFieldsToEmit()
internal override TypeLayout Layout => default(TypeLayout);

internal override bool HasSpecialName => false;

internal sealed override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable;

internal sealed override NamedTypeSymbol NativeIntegerUnderlyingType => null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r
moduleBuilder.Compilation.SynthesizeAttributeUsageAttribute(usageInfo.ValidTargets, usageInfo.AllowMultiple, usageInfo.Inherited));
}
}

internal sealed override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable;

internal sealed override NamedTypeSymbol NativeIntegerUnderlyingType => null;
}

/// <summary>
Expand Down
Loading