[codegen/hcl2] Fix assignability from dynamic.

Types like output(T), promise(T), and union(T_0, ..., T_N) should be
assignable from dynamic if they contain an element type that is
assignable from dynamic.

This allows consumers to use the following code to check if some type
behaves like the dynamic type w.r.t. conversions:

```
if t.AssignableFrom(model.DynamicType) {
}
```

Fixes #4703.
This commit is contained in:
Pat Gavlin 2020-05-26 08:21:09 -07:00
parent 5330c97684
commit 05032d6850
2 changed files with 23 additions and 7 deletions

View file

@ -61,13 +61,7 @@ var (
)
func assignableFrom(dest, src Type, assignableFrom func() bool) bool {
if dest.Equals(src) || dest == DynamicType {
return true
}
if src == DynamicType {
return false
}
return assignableFrom()
return dest.Equals(src) || dest == DynamicType || assignableFrom()
}
func conversionFrom(dest, src Type, unifying bool, conversionFrom func() ConversionKind) ConversionKind {

View file

@ -53,6 +53,28 @@ func TestDynamicType(t *testing.T) {
"int": IntType,
})))
// Test that DynamicType is assignable to certain types and not assignable to others.
assert.True(t, NewOptionalType(DynamicType).AssignableFrom(DynamicType))
assert.True(t, NewOutputType(DynamicType).AssignableFrom(DynamicType))
assert.True(t, NewPromiseType(DynamicType).AssignableFrom(DynamicType))
assert.True(t, NewUnionType(BoolType, DynamicType).AssignableFrom(DynamicType))
assert.False(t, BoolType.AssignableFrom(DynamicType))
assert.False(t, IntType.AssignableFrom(DynamicType))
assert.False(t, NumberType.AssignableFrom(DynamicType))
assert.False(t, StringType.AssignableFrom(DynamicType))
assert.False(t, NewOptionalType(BoolType).AssignableFrom(DynamicType))
assert.False(t, NewOutputType(BoolType).AssignableFrom(DynamicType))
assert.False(t, NewPromiseType(BoolType).AssignableFrom(DynamicType))
assert.False(t, NewMapType(BoolType).AssignableFrom(DynamicType))
assert.False(t, NewListType(BoolType).AssignableFrom(DynamicType))
assert.False(t, NewUnionType(BoolType, IntType).AssignableFrom(DynamicType))
assert.False(t, NewObjectType(map[string]Type{
"bool": BoolType,
"int": IntType,
}).AssignableFrom(DynamicType))
// Test that DynamicType is convertible from any type.
assert.True(t, DynamicType.ConversionFrom(BoolType).Exists())
assert.True(t, DynamicType.ConversionFrom(IntType).Exists())