lang: Check that set type matches actual expression

I forgot to include these two invariants which are occasionally
necessary, although in most cases they're necessary to prevent incorrect
code from getting past unification. In any case, they would have been
caught by the engine.
This commit is contained in:
James Shubin
2019-01-20 04:01:34 -05:00
parent 6c5c38f5a7
commit 32e29862f2
2 changed files with 21 additions and 0 deletions

View File

@@ -859,6 +859,7 @@ arg:
} }
; ;
bind: bind:
// `$s = "hey"`
VAR_IDENTIFIER EQUALS expr VAR_IDENTIFIER EQUALS expr
{ {
posLast(yylex, yyDollar) // our pos posLast(yylex, yyDollar) // our pos
@@ -867,6 +868,8 @@ bind:
Value: $3.expr, Value: $3.expr,
} }
} }
// `$x bool = true`
// `$x int = if true { 42 } else { 13 }`
| VAR_IDENTIFIER type EQUALS expr | VAR_IDENTIFIER type EQUALS expr
{ {
posLast(yylex, yyDollar) // our pos posLast(yylex, yyDollar) // our pos

View File

@@ -5255,6 +5255,15 @@ func (obj *ExprVar) Unify() ([]interfaces.Invariant, error) {
return nil, fmt.Errorf("var `%s` does not exist in this scope", obj.Name) return nil, fmt.Errorf("var `%s` does not exist in this scope", obj.Name)
} }
// if this was set explicitly by the parser
if obj.typ != nil {
invar := &unification.EqualsInvariant{
Expr: obj,
Type: obj.typ,
}
invariants = append(invariants, invar)
}
// don't recurse because we already got this through the bind statement // don't recurse because we already got this through the bind statement
//invars, err := expr.Unify() //invars, err := expr.Unify()
//if err != nil { //if err != nil {
@@ -5531,6 +5540,15 @@ func (obj *ExprIf) Type() (*types.Type, error) {
func (obj *ExprIf) Unify() ([]interfaces.Invariant, error) { func (obj *ExprIf) Unify() ([]interfaces.Invariant, error) {
var invariants []interfaces.Invariant var invariants []interfaces.Invariant
// if this was set explicitly by the parser
if obj.typ != nil {
invar := &unification.EqualsInvariant{
Expr: obj,
Type: obj.typ,
}
invariants = append(invariants, invar)
}
// conditional expression might have some children invariants to share // conditional expression might have some children invariants to share
condition, err := obj.Condition.Unify() condition, err := obj.Condition.Unify()
if err != nil { if err != nil {