Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions checker/checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1856,6 +1856,58 @@ _&&_(_==_(list~type(list(dyn))^list,
)~bool^logical_and
)~bool^logical_and`,
},
{
in: `[1].map(x, [x, x]).map(x, [x, x])`,
outType: decls.NewListType(decls.NewListType(decls.NewListType(decls.Int))),
out: `__comprehension__(
// Variable
x,
// Target
__comprehension__(
// Variable
x,
// Target
[
1~int
]~list(int),
// Accumulator
__result__,
// Init
[]~list(list(int)),
// LoopCondition
true~bool,
// LoopStep
_+_(
__result__~list(list(int))^__result__,
[
[
x~int^x,
x~int^x
]~list(int)
]~list(list(int))
)~list(list(int))^add_list,
// Result
__result__~list(list(int))^__result__)~list(list(int)),
// Accumulator
__result__,
// Init
[]~list(list(list(int))),
// LoopCondition
true~bool,
// LoopStep
_+_(
__result__~list(list(list(int)))^__result__,
[
[
x~list(int)^x,
x~list(int)^x
]~list(list(int))
]~list(list(list(int)))
)~list(list(list(int)))^add_list,
// Result
__result__~list(list(list(int)))^__result__)~list(list(list(int)))
`,
},
}

var testEnvs = map[string]testEnv{
Expand Down
10 changes: 8 additions & 2 deletions checker/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,15 @@ func internalIsAssignable(m *mapping, t1 *exprpb.Type, t2 *exprpb.Type) bool {
// - t2 has a type substitution (t2sub) assignable to t1
// - t2 does not occur within t1.
func isValidTypeSubstitution(m *mapping, t1, t2 *exprpb.Type) (valid, hasSub bool) {
// Early return if the t1 and t2 are the same instance.
kind1, kind2 := kindOf(t1), kindOf(t2)
if kind1 == kind2 && (t1 == t2 || proto.Equal(t1, t2)) {
return true, true
}
if t2Sub, found := m.find(t2); found {
kind1, kind2 := kindOf(t1), kindOf(t2)
if kind1 == kind2 && proto.Equal(t1, t2Sub) {
// Early return if t1 and t2Sub are the same instance as otherwise the mapping
// might mark a type as being a subtitution for itself.
if kind1 == kindOf(t2Sub) && (t1 == t2Sub || proto.Equal(t1, t2Sub)) {
return true, true
}
// If the types are compatible, pick the more general type and return true
Expand Down