+
+ if diag.Expression != nil && diag.EvalContext != nil {
+ // We will attempt to render the values for any variables
+ // referenced in the given expression as additional context, for
+ // situations where the same expression is evaluated multiple
+ // times in different scopes.
+ expr := diag.Expression
+ ctx := diag.EvalContext
+
+ vars := expr.Variables()
+ stmts := make([]string, 0, len(vars))
+ seen := make(map[string]struct{}, len(vars))
+ for _, traversal := range vars {
+ val, diags := traversal.TraverseAbs(ctx)
+ if diags.HasErrors() {
+ // Skip anything that generates errors, since we probably
+ // already have the same error in our diagnostics set
+ // already.
+ continue
+ }
+
+ traversalStr := w.traversalStr(traversal)
+ if _, exists := seen[traversalStr]; exists {
+ continue // don't show duplicates when the same variable is referenced multiple times
+ }
+ switch {
+ case !val.IsKnown():
+ // Can't say anything about this yet, then.
+ continue
+ case val.IsNull():
+ stmts = append(stmts, fmt.Sprintf("%s set to null", traversalStr))
+ default:
+ stmts = append(stmts, fmt.Sprintf("%s as %s", traversalStr, w.valueStr(val)))
+ }
+ seen[traversalStr] = struct{}{}
+ }
+
+ sort.Strings(stmts) // FIXME: Should maybe use a traversal-aware sort that can sort numeric indexes properly?
+ last := len(stmts) - 1
+
+ for i, stmt := range stmts {
+ switch i {
+ case 0:
+ w.wr.Write([]byte{'w', 'i', 't', 'h', ' '})
+ default:
+ w.wr.Write([]byte{' ', ' ', ' ', ' ', ' '})
+ }
+ w.wr.Write([]byte(stmt))
+ switch i {
+ case last:
+ w.wr.Write([]byte{'.', '\n', '\n'})
+ default:
+ w.wr.Write([]byte{',', '\n'})
+ }
+ }
+ }