private bool bindImplicitConversionBetweenSimpleTypes(AggregateType aggTypeSrc)
{
AggregateSymbol aggSrc = aggTypeSrc.getAggregate();
Debug.Assert(aggSrc.getThisType().isSimpleType());
Debug.Assert(_typeDest.isSimpleType());
Debug.Assert(aggSrc.IsPredefined() && _typeDest.isPredefined());
PredefinedType ptSrc = aggSrc.GetPredefType();
PredefinedType ptDest = _typeDest.getPredefType();
ConvKind convertKind;
bool fConstShrinkCast = false;
Debug.Assert((int)ptSrc < NUM_SIMPLE_TYPES && (int)ptDest < NUM_SIMPLE_TYPES);
// 13.1.7 Implicit constant expression conversions
//
// An implicit constant expression conversion permits the following conversions:
// * A constant-expression (14.16) of type int can be converted to type sbyte, byte, short,
// ushort, uint, or ulong, provided the value of the constant-expression is within the range
// of the destination type.
// * A constant-expression of type long can be converted to type ulong, provided the value of
// the constant-expression is not negative.
// Note: Don't use GetConst here since the conversion only applies to bona-fide compile time constants.
if (_exprSrc is ExprConstant constant && _exprSrc.IsOK &&
((ptSrc == PredefinedType.PT_INT && ptDest != PredefinedType.PT_BOOL && ptDest != PredefinedType.PT_CHAR) ||
(ptSrc == PredefinedType.PT_LONG && ptDest == PredefinedType.PT_ULONG)) &&
isConstantInRange(constant, _typeDest))
{
// Special case (CLR 6.1.6): if integral constant is in range, the conversion is a legal implicit conversion.
convertKind = ConvKind.Implicit;
fConstShrinkCast = _needsExprDest && (GetConvKind(ptSrc, ptDest) != ConvKind.Implicit);
}