// Conversion type-checks the conversion T(x). // The result is in x. func (check *Checker) conversion(x *operand, T Type) { constArg := x.mode == constant var ok bool switch { case constArg && isConstType(T): // constant conversion switch t := T.Underlying().(*Basic); { case representableConst(x.val, check.conf, t.kind, &x.val): ok = true case isInteger(x.typ) && isString(t): codepoint := int64(-1) if i, ok := exact.Int64Val(x.val); ok { codepoint = i } // If codepoint < 0 the absolute value is too large (or unknown) for // conversion. This is the same as converting any other out-of-range // value - let string(codepoint) do the work. x.val = exact.MakeString(string(codepoint)) ok = true } case x.convertibleTo(check.conf, T): // non-constant conversion x.mode = value ok = true } if !ok { check.errorf(x.pos(), "cannot convert %s to %s", x, T) x.mode = invalid return } // The conversion argument types are final. For untyped values the // conversion provides the type, per the spec: "A constant may be // given a type explicitly by a constant declaration or conversion,...". final := x.typ if isUntyped(x.typ) { final = T // - For conversions to interfaces, use the argument's default type. // - For conversions of untyped constants to non-constant types, also // use the default type (e.g., []byte("foo") should report string // not []byte as type for the constant "foo"). // - Keep untyped nil for untyped nil arguments. if IsInterface(T) || constArg && !isConstType(T) { final = defaultType(x.typ) } check.updateExprType(x.expr, final, true) } x.typ = T }
func (c *checker) InsertMetricValuesFromContext(m *metrics.MetricContext) error { for metricName, metric := range m.Gauges { name := strings.Replace(metricName, ".", "_", -1) + "_value" c.sc.Insert(types.NewConst(0, c.pkg, name, types.Typ[types.Float64], exact.MakeFloat64(metric.Get()))) sname := name + "_string" c.sc.Insert(types.NewConst(0, c.pkg, sname, types.Typ[types.String], exact.MakeString(fmt.Sprintf("%0.2f", metric.Get())))) } for metricName, metric := range m.Counters { name := strings.Replace(metricName, ".", "_", -1) + "_current" c.sc.Insert(types.NewConst(0, c.pkg, name, types.Typ[types.Uint64], exact.MakeUint64(metric.Get()))) sname := name + "_string" c.sc.Insert(types.NewConst(0, c.pkg, sname, types.Typ[types.String], exact.MakeString(fmt.Sprintf("%d", metric.Get())))) name = strings.Replace(metricName, ".", "_", -1) + "_rate" c.sc.Insert(types.NewConst(0, c.pkg, name, types.Typ[types.Float64], exact.MakeFloat64(metric.ComputeRate()))) } return nil }