Skip to content

Commit b1a4981

Browse files
committed
Fixed optional unification
1 parent 7e80c55 commit b1a4981

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

Sources/Compiler/Sema/InferenceState.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ extension InferenceState {
166166
case (.error, _), (_, .error):
167167
// Already had an upstream error so no need to emit any more diagnostics
168168
return
169+
169170
case let (.var(tv1), .var(tv2)):
170171
// Unify to type variables.
171172
// We need to prioritize what gets substituded for what
@@ -177,39 +178,69 @@ extension InferenceState {
177178
} else {
178179
substitute(tv1, for: other)
179180
}
181+
182+
// When two optionals, unify wrapped type.
180183
case let (.optional(t1), .optional(t2)):
181184
unify(t1, with: t2, at: location)
185+
186+
// tyVar with optional tyVar
182187
case let (.var(nonOptional), .optional(.var(optional))):
183188
let kind = max(nonOptional.kind, optional.kind)
184189
substitute(nonOptional, for: .optional(.var(optional.with(kind: kind))))
190+
191+
// tyVar with optional tyVar
185192
case let (.optional(.var(optional)), .var(nonOptional)):
186193
let kind = max(nonOptional.kind, optional.kind)
187194
substitute(nonOptional, for: .optional(.var(optional.with(kind: kind))))
195+
196+
// Optional tyVar with concrete type
197+
case let (.optional(.var(optional)), t):
198+
substitute(optional, for: .optional(t))
199+
200+
// Optional tyVar with concrete type
201+
case let (t, .optional(.var(optional))):
202+
substitute(optional, for: .optional(t))
203+
204+
// tyVar with concrete type
188205
case let (.var(tv), ty):
189206
validateCanUnify(type: ty, with: tv.kind, at: location)
190207
substitute(tv, for: ty)
208+
209+
// tyVar with concrete type
191210
case let (ty, .var(tv)):
192211
validateCanUnify(type: ty, with: tv.kind, at: location)
193212
substitute(tv, for: ty)
213+
194214
case (.integer, .real), (.real, .integer), (.any, _), (_, .any):
195215
return // Not equal but valid to use together
216+
196217
case let (.fn(args1, ret1), .fn(args2, ret2)):
197218
unify(args1, with: args2, at: location)
198219
unify(ret1.apply(substitution), with: ret2.apply(substitution), at: location)
220+
221+
// Row with value of 1 is unifiable to the inner type
222+
// (INTEGER) == INTEGER
199223
case let (.row(row), t) where row.count == 1 && !t.isRow:
200224
unify(row.first!, with: t, at: location)
225+
201226
case let (t, .row(row)) where row.count == 1 && !t.isRow:
202227
unify(row.first!, with: t, at: location)
228+
203229
case let (.row(.unknown(ty)), .row(rhs)):
204230
return unify(all: rhs.types, with: ty, at: location)
231+
205232
case let (.row(lhs), .row(.unknown(ty))):
206233
return unify(all: lhs.types, with: ty, at: location)
234+
207235
case let (.row(rhs), .row(lhs)) where lhs.count == rhs.count:
208236
return unify(rhs.types, with: lhs.types, at: location)
237+
209238
case let (.alias(t1, _), t2):
210239
return unify(t1, with: t2, at: location)
240+
211241
case let (t1, .alias(t2, _)):
212242
return unify(t2, with: t1, at: location)
243+
213244
default:
214245
guard type.root != other.root else { return }
215246
diagnostics.add(.unableToUnify(type, with: other, at: location))

0 commit comments

Comments
 (0)