fix: reconcile the ERROR markers with what the checker reports

Checking the markers for the first time found five disagreements in areas that
are implemented. Four were the marker's fault:

- own/badarg pinned "self", but the rule being broken is that a returned
  reference must derive from a parameter -- `self` has nothing to do with it.
- own/badbrmov pinned line 9, which is the closing brace; the second destroy is
  on line 8.
- own/badloop pinned line 8, the destroy after the loop. The diagnostic is on
  line 6, inside it, and line 6 is right: the second iteration moves the same
  value again, so the loop body is where it is caught. Whoever wrote the marker
  expected the error after the loop.
- optional/badcatch pinned line 14, the body of the catch block. The catch
  expression on line 13 is what cannot fall through.

The fifth was the compiler's. own/badweak assigns a `&mut i32` to a `&i32` and
got "initializer type mismatch", which says nothing about why. Weakening an
exclusive borrow to a shared one is a specific rule and now says so, for
references and slices alike.

own/ is fully green: 50/50. Overall 133 -> 138 of 188. The six remaining marker
disagreements are all under units/ and generic/, where nothing is implemented
yet, so there is no diagnostic to compare against and no way to tell whether
the marker is right.
This commit is contained in:
2026-08-17 03:42:06 +09:00
parent fb65152901
commit 547d8c5ec2
5 changed files with 20 additions and 6 deletions
+15 -1
View File
@@ -2489,8 +2489,22 @@ static void m7_check_decl_stmt(FeCheckerState *s, FeNode *n, int mutable)
if (expected && expected->kind==FE_TYPE_VOID)
err(s->c,n->loc,"variable cannot have void type");
if (n->b && !fe_type_equal(expected,stored) &&
!m7_actual_compatible(expected,stored,n->b))
!m7_actual_compatible(expected,stored,n->b)) {
/* Say which rule was hit. Weakening &mut to & is a distinct thing from
two unrelated types not matching, and "type mismatch" told the reader
nothing about why the exclusive borrow could not be shared. */
if (expected && stored && expected->kind==FE_TYPE_REF &&
stored->kind==FE_TYPE_REF && !expected->ref_mut && stored->ref_mut)
err(s->c,n->loc,
"cannot rebind a mut borrow as a shared reference");
else if (expected && stored && expected->kind==FE_TYPE_SLICE &&
stored->kind==FE_TYPE_SLICE && !expected->ref_mut &&
stored->ref_mut)
err(s->c,n->loc,
"cannot rebind a mut slice as a shared slice");
else
err(s->c,n->loc,"initializer type mismatch");
}
/* Rules the M6 declaration case carried that this one has to repeat now
that it is the only declaration case. */
if (n->b && stored && stored->kind==FE_TYPE_VOID)
+1 -1
View File
@@ -1,4 +1,4 @@
// ERROR:14:catch
// ERROR:13:catch
unit badcatch;
error E {
+1 -1
View File
@@ -1,4 +1,4 @@
// ERROR:8:self
// ERROR:8:derived from a parameter
unit badarg;
struct Box {
+1 -1
View File
@@ -1,4 +1,4 @@
// ERROR:9:move
// ERROR:8:move
unit badbrmov;
fn bad(p: ^i32, consume: bool) -> void {
+1 -1
View File
@@ -1,4 +1,4 @@
// ERROR:8:move
// ERROR:6:move
unit badloop;
fn bad(p: ^i32, again: bool) -> void {