mirror of
https://github.com/roc-lang/roc.git
synced 2025-11-11 09:08:57 +00:00
More error message improvements
This commit is contained in:
parent
9a3bb0face
commit
cc597648a0
17 changed files with 75 additions and 25 deletions
|
|
@ -155,6 +155,23 @@ pub fn unify(self: *Self, a: Var, b: Var) std.mem.Allocator.Error!unifier.Result
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unifyWithAnnotation(self: *Self, a: Var, b: Var) std.mem.Allocator.Error!unifier.Result {
|
||||||
|
const trace = tracy.trace(@src());
|
||||||
|
defer trace.end();
|
||||||
|
|
||||||
|
return try unifier.unifyWithContext(
|
||||||
|
self.cir,
|
||||||
|
self.types,
|
||||||
|
&self.problems,
|
||||||
|
&self.snapshots,
|
||||||
|
&self.unify_scratch,
|
||||||
|
&self.occurs_scratch,
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
true, // from_annotation = true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// instantiate //
|
// instantiate //
|
||||||
|
|
||||||
const InstantiateRegionBehavior = union(enum) {
|
const InstantiateRegionBehavior = union(enum) {
|
||||||
|
|
@ -406,7 +423,7 @@ fn checkDef(self: *Self, def_idx: CIR.Def.Idx) std.mem.Allocator.Error!void {
|
||||||
_ = try self.checkExpr(def.expr);
|
_ = try self.checkExpr(def.expr);
|
||||||
|
|
||||||
// Unify the expression with its annotation
|
// Unify the expression with its annotation
|
||||||
_ = try self.unify(expr_var, anno_var);
|
_ = try self.unifyWithAnnotation(expr_var, anno_var);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Check the expr
|
// Check the expr
|
||||||
|
|
@ -1469,7 +1486,7 @@ fn checkLambdaWithAnno(
|
||||||
|
|
||||||
// Unify against the annotation
|
// Unify against the annotation
|
||||||
const pattern_var = ModuleEnv.varFrom(pattern_idx);
|
const pattern_var = ModuleEnv.varFrom(pattern_idx);
|
||||||
_ = try self.unify(pattern_var, expected_arg);
|
_ = try self.unifyWithAnnotation(pattern_var, expected_arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1493,12 +1510,12 @@ fn checkLambdaWithAnno(
|
||||||
|
|
||||||
// STEP 4: Validate the function body against the annotation return type
|
// STEP 4: Validate the function body against the annotation return type
|
||||||
if (mb_expected_func) |func| {
|
if (mb_expected_func) |func| {
|
||||||
_ = try self.unify(return_var, func.ret);
|
_ = try self.unifyWithAnnotation(return_var, func.ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STEP 5: Validate the entire function against the annotation
|
// STEP 5: Validate the entire function against the annotation
|
||||||
if (mb_expected_var) |expected_var| {
|
if (mb_expected_var) |expected_var| {
|
||||||
_ = try self.unify(fn_var, expected_var);
|
_ = try self.unifyWithAnnotation(fn_var, expected_var);
|
||||||
}
|
}
|
||||||
|
|
||||||
return is_effectful;
|
return is_effectful;
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,8 @@ pub const TypePair = struct {
|
||||||
expected_snapshot: SnapshotContentIdx,
|
expected_snapshot: SnapshotContentIdx,
|
||||||
actual_var: Var,
|
actual_var: Var,
|
||||||
actual_snapshot: SnapshotContentIdx,
|
actual_snapshot: SnapshotContentIdx,
|
||||||
|
/// True if the expected type comes from a type annotation
|
||||||
|
from_annotation: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// More specific details about a particular type mismatch.
|
/// More specific details about a particular type mismatch.
|
||||||
|
|
@ -335,7 +337,11 @@ pub const ReportBuilder = struct {
|
||||||
);
|
);
|
||||||
try report.document.addLineBreak();
|
try report.document.addLineBreak();
|
||||||
|
|
||||||
try report.document.addText("The type annotation says it should have the type:");
|
if (types.from_annotation) {
|
||||||
|
try report.document.addText("The type annotation says it should have the type:");
|
||||||
|
} else {
|
||||||
|
try report.document.addText("It is of type:");
|
||||||
|
}
|
||||||
try report.document.addLineBreak();
|
try report.document.addLineBreak();
|
||||||
try report.document.addText(" ");
|
try report.document.addText(" ");
|
||||||
try report.document.addAnnotated(owned_actual, .type_variable);
|
try report.document.addAnnotated(owned_actual, .type_variable);
|
||||||
|
|
|
||||||
|
|
@ -114,13 +114,8 @@ pub const Result = union(enum) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Unify two type variables
|
/// Unify two type variables with context about whether this is from an annotation
|
||||||
///
|
pub fn unifyWithContext(
|
||||||
/// This function
|
|
||||||
/// * Resolves type variables & compresses paths
|
|
||||||
/// * Compares variable contents for equality
|
|
||||||
/// * Merges unified variables so 1 is "root" and the other is "redirect"
|
|
||||||
pub fn unify(
|
|
||||||
module_env: *ModuleEnv,
|
module_env: *ModuleEnv,
|
||||||
types: *types_mod.Store,
|
types: *types_mod.Store,
|
||||||
problems: *problem_mod.Store,
|
problems: *problem_mod.Store,
|
||||||
|
|
@ -129,6 +124,7 @@ pub fn unify(
|
||||||
occurs_scratch: *occurs.Scratch,
|
occurs_scratch: *occurs.Scratch,
|
||||||
a: Var,
|
a: Var,
|
||||||
b: Var,
|
b: Var,
|
||||||
|
from_annotation: bool,
|
||||||
) std.mem.Allocator.Error!Result {
|
) std.mem.Allocator.Error!Result {
|
||||||
const trace = tracy.trace(@src());
|
const trace = tracy.trace(@src());
|
||||||
defer trace.end();
|
defer trace.end();
|
||||||
|
|
@ -153,6 +149,7 @@ pub fn unify(
|
||||||
.expected_snapshot = expected_snapshot,
|
.expected_snapshot = expected_snapshot,
|
||||||
.actual_var = b,
|
.actual_var = b,
|
||||||
.actual_snapshot = actual_snapshot,
|
.actual_snapshot = actual_snapshot,
|
||||||
|
.from_annotation = from_annotation,
|
||||||
},
|
},
|
||||||
.detail = null,
|
.detail = null,
|
||||||
} };
|
} };
|
||||||
|
|
@ -287,6 +284,36 @@ pub fn unify(
|
||||||
return .ok;
|
return .ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Unify two type variables
|
||||||
|
///
|
||||||
|
/// This function
|
||||||
|
/// * Resolves type variables & compresses paths
|
||||||
|
/// * Compares variable contents for equality
|
||||||
|
/// * Merges unified variables so 1 is "root" and the other is "redirect"
|
||||||
|
pub fn unify(
|
||||||
|
module_env: *ModuleEnv,
|
||||||
|
types: *types_mod.Store,
|
||||||
|
problems: *problem_mod.Store,
|
||||||
|
snapshots: *snapshot_mod.Store,
|
||||||
|
unify_scratch: *Scratch,
|
||||||
|
occurs_scratch: *occurs.Scratch,
|
||||||
|
a: Var,
|
||||||
|
b: Var,
|
||||||
|
) std.mem.Allocator.Error!Result {
|
||||||
|
// Default to not from annotation for backward compatibility
|
||||||
|
return unifyWithContext(
|
||||||
|
module_env,
|
||||||
|
types,
|
||||||
|
problems,
|
||||||
|
snapshots,
|
||||||
|
unify_scratch,
|
||||||
|
occurs_scratch,
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
false, // from_annotation = false by default
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// A temporary unification context used to unify two type variables within a `Store`.
|
/// A temporary unification context used to unify two type variables within a `Store`.
|
||||||
///
|
///
|
||||||
/// `Unifier` is created per unification call and:
|
/// `Unifier` is created per unification call and:
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ This expression is used in an unexpected way:
|
||||||
```
|
```
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
_Bool_
|
_Bool_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
|
|
@ -875,7 +875,7 @@ This expression is used in an unexpected way:
|
||||||
)crash ke"Unr!" #)
|
)crash ke"Unr!" #)
|
||||||
```
|
```
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
__arg -> _ret_
|
__arg -> _ret_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
|
|
@ -961,7 +961,7 @@ This expression is used in an unexpected way:
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
__arg -> _ret_
|
__arg -> _ret_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
|
|
@ -912,7 +912,7 @@ This expression is used in an unexpected way:
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
__arg -> _ret_
|
__arg -> _ret_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -26,7 +26,7 @@ string_function = |x| x + 42
|
||||||
```
|
```
|
||||||
^
|
^
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
_Str_
|
_Str_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ makeAdder = |x| |y| x + y
|
||||||
```
|
```
|
||||||
^
|
^
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
_a_
|
_a_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ addTwoF64 = |x| x + 2.0
|
||||||
```
|
```
|
||||||
^
|
^
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
_F64_
|
_F64_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
|
|
@ -897,7 +897,7 @@ This expression is used in an unexpected way:
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
__arg -> _ret_
|
__arg -> _ret_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ This expression is used in an unexpected way:
|
||||||
```
|
```
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
_Num(_size), Num(_size2), Num(_size3) -> Num(_size4), Num(_size5) -> Num(_size6) -> _ret_
|
_Num(_size), Num(_size2), Num(_size3) -> Num(_size4), Num(_size5) -> Num(_size6) -> _ret_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ This expression is used in an unexpected way:
|
||||||
```
|
```
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
_Num(_size), Num(_size2) -> _ret_
|
_Num(_size), Num(_size2) -> _ret_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ main = swap(1, 2)
|
||||||
```
|
```
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
_Num(_size), Num(_size2) -> _ret_
|
_Num(_size), Num(_size2) -> _ret_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ main! = |_| swapPair(1, 2)
|
||||||
```
|
```
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
_Num(_size), Num(_size2) -> _ret_
|
_Num(_size), Num(_size2) -> _ret_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ main! = |_| mapList([1,2,3,4,5])
|
||||||
```
|
```
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
The type annotation says it should have the type:
|
It is of type:
|
||||||
_List(Num(_size)) -> _ret_
|
_List(Num(_size)) -> _ret_
|
||||||
|
|
||||||
But you are trying to use it as:
|
But you are trying to use it as:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue