From 0d0da200a22668fd26e18a64334edee141baa3a6 Mon Sep 17 00:00:00 2001 From: Alisdair McDiarmid Date: Mon, 23 Nov 2020 13:19:42 -0500 Subject: [PATCH] convert: Fix MismatchMessage for object attributes When determining which object attributes cause a type mismatch, we must disregard equal attribute types. Previously we would attempt to find a conversion between them, deciding that the attribute type was a mismatch if no conversion exists. However, this is invalid if the two types are equal, because GetConversion returns nil for equal primitive types. Because of non-deterministic map iteration order, the test case added in this commit failed approximately 2/3 of the time before the change. It now passes consistently. --- cty/convert/mismatch_msg.go | 4 ++++ cty/convert/mismatch_msg_test.go | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/cty/convert/mismatch_msg.go b/cty/convert/mismatch_msg.go index 0bd0cffa..5c1e114d 100644 --- a/cty/convert/mismatch_msg.go +++ b/cty/convert/mismatch_msg.go @@ -84,6 +84,10 @@ func mismatchMessageObjects(got, want cty.Type) string { continue } + if gotAty.Equals(wantAty) { + continue // exact match, so no problem + } + // We'll now try to convert these attributes in isolation and // see if we have a nested conversion error to report. // We'll try an unsafe conversion first, and then fall back on diff --git a/cty/convert/mismatch_msg_test.go b/cty/convert/mismatch_msg_test.go index 186fc99d..9963f5ff 100644 --- a/cty/convert/mismatch_msg_test.go +++ b/cty/convert/mismatch_msg_test.go @@ -104,6 +104,24 @@ func TestMismatchMessage(t *testing.T) { cty.List(cty.DynamicPseudoType), `all list elements must have the same type`, }, + { + cty.Object(map[string]cty.Type{ + "foo": cty.Bool, + "bar": cty.String, + "baz": cty.Object(map[string]cty.Type{ + "boop": cty.Number, + }), + }), + cty.Object(map[string]cty.Type{ + "foo": cty.Bool, + "bar": cty.String, + "baz": cty.Object(map[string]cty.Type{ + "boop": cty.Number, + "beep": cty.Bool, + }), + }), + `attribute "baz": attribute "beep" is required`, + }, } for _, test := range tests {