addOrRefine either adds a binding or intersects type for an existing one.
(v ast.Variable, tpe ast.BaseTerm)
| 53 | |
| 54 | // addOrRefine either adds a binding or intersects type for an existing one. |
| 55 | func (s *inferState) addOrRefine(v ast.Variable, tpe ast.BaseTerm) error { |
| 56 | if tpe.Equals(symbols.EmptyType) { |
| 57 | return fmt.Errorf("variable %v has empty type", v) |
| 58 | } |
| 59 | if v.Symbol == "_" { |
| 60 | return nil |
| 61 | } |
| 62 | i := s.usedVars.Find(v) |
| 63 | if i == -1 { |
| 64 | s.usedVars = s.usedVars.Extend([]ast.Variable{v}) |
| 65 | s.varTpe = append(s.varTpe, tpe) |
| 66 | return nil |
| 67 | } |
| 68 | tpe = symbols.LowerBound(nil /*TODO*/, []ast.BaseTerm{s.varTpe[i], tpe}) |
| 69 | if tpe.Equals(symbols.EmptyType) { |
| 70 | return fmt.Errorf("variable %v cannot have both %v and %v", v, s.varTpe[i], tpe) |
| 71 | } |
| 72 | s.varTpe[i] = tpe |
| 73 | return nil |
| 74 | } |
| 75 | |
| 76 | // refineNegative uses negative information to refine an existing binding |
| 77 | func (s *inferState) refineNegative(v ast.Variable, tpe ast.BaseTerm) error { |
no test coverage detected