private bool CandidateOperators( ArrayBuilder <UnaryOperatorSignature> operators, BoundExpression operand, ArrayBuilder <UnaryOperatorAnalysisResult> results, ref CompoundUseSiteInfo <AssemblySymbol> useSiteInfo ) { bool anyApplicable = false; foreach (var op in operators) { var conversion = Conversions.ClassifyConversionFromExpression( operand, op.OperandType, ref useSiteInfo ); if (conversion.IsImplicit) { anyApplicable = true; results.Add(UnaryOperatorAnalysisResult.Applicable(op, conversion)); } else { results.Add(UnaryOperatorAnalysisResult.Inapplicable(op, conversion)); } } return(anyApplicable); }
protected BoundExpression ConvertCaseExpression(CSharpSyntaxNode node, BoundExpression caseExpression, Binder sectionBinder, ref ConstantValue constantValueOpt, DiagnosticBag diagnostics, bool isGotoCaseExpr = false) { if (isGotoCaseExpr) { // SPEC VIOLATION for Dev10 COMPATIBILITY: // Dev10 compiler violates the SPEC comment below: // "if the constant-expression is not implicitly convertible (§6.1) to // the governing type of the nearest enclosing switch statement, // a compile-time error occurs" // If there is no implicit conversion from gotoCaseExpression to switchGoverningType, // but there exists an explicit conversion, Dev10 compiler generates a warning "WRN_GotoCaseShouldConvert" // instead of an error. See test "CS0469_NoImplicitConversionWarning". HashSet <DiagnosticInfo> useSiteDiagnostics = null; Conversion conversion = Conversions.ClassifyConversionFromExpression(caseExpression, SwitchGoverningType, ref useSiteDiagnostics); diagnostics.Add(node, useSiteDiagnostics); if (!conversion.IsValid) { GenerateImplicitConversionError(diagnostics, node, conversion, caseExpression, SwitchGoverningType); } else if (!conversion.IsImplicit) { diagnostics.Add(ErrorCode.WRN_GotoCaseShouldConvert, node.Location, SwitchGoverningType); } caseExpression = CreateConversion(caseExpression, conversion, SwitchGoverningType, diagnostics); } return(ConvertPatternExpression(SwitchGoverningType, node, caseExpression, ref constantValueOpt, diagnostics)); }
private BoundExpression ConvertCaseExpression(TypeSymbol switchGoverningType, CSharpSyntaxNode node, BoundExpression caseExpression, ref ConstantValue constantValueOpt, DiagnosticBag diagnostics, bool isGotoCaseExpr = false) { BoundExpression convertedCaseExpression; if (!isGotoCaseExpr) { // NOTE: This will allow user-defined conversions, even though they're not allowed here. This is acceptable // because the result of a user-defined conversion does not have a ConstantValue and we'll report a diagnostic // to that effect below (same error code as Dev10). convertedCaseExpression = GenerateConversionForAssignment(switchGoverningType, caseExpression, diagnostics); } else { // SPEC VIOLATION for Dev10 COMPATIBILITY: // Dev10 compiler violates the SPEC comment below: // "if the constant-expression is not implicitly convertible (§6.1) to // the governing type of the nearest enclosing switch statement, // a compile-time error occurs" // If there is no implicit conversion from gotoCaseExpression to switchGoverningType, // but there exists an explicit conversion, Dev10 compiler generates a warning "WRN_GotoCaseShouldConvert" // instead of an error. See test "CS0469_NoImplicitConversionWarning". // CONSIDER: Should we introduce a breaking change and violate Dev10 compatibility and follow the spec? HashSet <DiagnosticInfo> useSiteDiagnostics = null; Conversion conversion = Conversions.ClassifyConversionFromExpression(caseExpression, switchGoverningType, ref useSiteDiagnostics); diagnostics.Add(node, useSiteDiagnostics); if (!conversion.IsValid) { GenerateImplicitConversionError(diagnostics, node, conversion, caseExpression, switchGoverningType); } else if (!conversion.IsImplicit) { diagnostics.Add(ErrorCode.WRN_GotoCaseShouldConvert, node.Location, switchGoverningType); } convertedCaseExpression = this.CreateConversion(caseExpression, conversion, switchGoverningType, diagnostics); } if (switchGoverningType.IsNullableType() && convertedCaseExpression.Kind == BoundKind.Conversion // Null is a special case here because we want to compare null to the Nullable<T> itself, not to the underlying type. && (convertedCaseExpression.ConstantValue == null || !convertedCaseExpression.ConstantValue.IsNull)) { var operand = ((BoundConversion)convertedCaseExpression).Operand; // We are not intested in the diagnostic that get created here var diagnosticBag = DiagnosticBag.GetInstance(); constantValueOpt = CreateConversion(operand, switchGoverningType.GetNullableUnderlyingType(), diagnosticBag).ConstantValue; diagnosticBag.Free(); } else { constantValueOpt = convertedCaseExpression.ConstantValue; } return(convertedCaseExpression); }