// If binder is null, then get it from the compilation. Otherwise use the provided binder.
        // Don't always get it from the compilation because we might be in a speculative context (local function parameter),
        // in which case the declaring compilation is the wrong one.
        protected ConstantValue MakeDefaultExpression(DiagnosticBag diagnostics, Binder binder)
        {
            var parameterSyntax = this.CSharpSyntaxNode;

            if (parameterSyntax == null)
            {
                return(ConstantValue.NotAvailable);
            }

            var defaultSyntax = parameterSyntax.Default;

            if (defaultSyntax == null)
            {
                return(ConstantValue.NotAvailable);
            }

            if (binder == null)
            {
                var syntaxTree    = _syntaxRef.SyntaxTree;
                var compilation   = this.DeclaringCompilation;
                var binderFactory = compilation.GetBinderFactory(syntaxTree);
                binder = binderFactory.GetBinder(defaultSyntax);
            }

            Debug.Assert(binder.GetBinder(defaultSyntax) == null);

            Binder binderForDefault = binder.CreateBinderForParameterDefaultValue(this, defaultSyntax);

            Debug.Assert(binderForDefault.InParameterDefaultValue);
            Debug.Assert(binderForDefault.ContainingMemberOrLambda == ContainingSymbol);

            BoundExpression valueBeforeConversion;
            var             convertedExpression = binderForDefault.BindParameterDefaultValue(defaultSyntax, parameterType, diagnostics, out valueBeforeConversion);

            bool hasErrors = ParameterHelpers.ReportDefaultParameterErrors(binder, ContainingSymbol, parameterSyntax, this, valueBeforeConversion, diagnostics);

            if (hasErrors)
            {
                return(ConstantValue.Bad);
            }

            // If we have something like M(double? x = 1) then the expression we'll get is (double?)1, which
            // does not have a constant value. The constant value we want is (double)1.

            if (convertedExpression.ConstantValue == null && convertedExpression.Kind == BoundKind.Conversion)
            {
                if (parameterType.IsNullableType())
                {
                    convertedExpression = binder.GenerateConversionForAssignment(parameterType.GetNullableUnderlyingType(),
                                                                                 valueBeforeConversion, diagnostics, isDefaultParameter: true);
                }
            }

            // represent default(struct) by a Null constant:
            var value = convertedExpression.ConstantValue ?? ConstantValue.Null;

            VerifyParamDefaultValueMatchesAttributeIfAny(value, defaultSyntax.Value, diagnostics);
            return(value);
        }