From 547d8c5ec29ba1bdba2c0c0b7e1b8a4ea997735a Mon Sep 17 00:00:00 2001 From: Sebastian Jeong Date: Mon, 17 Aug 2026 03:42:06 +0900 Subject: [PATCH] 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. --- fec/src/check.c | 18 ++++++++++++++++-- fec/tests/optional/badcatch.fe | 2 +- fec/tests/own/badarg.fe | 2 +- fec/tests/own/badbrmov.fe | 2 +- fec/tests/own/badloop.fe | 2 +- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/fec/src/check.c b/fec/src/check.c index 141d443..37e4370 100644 --- a/fec/src/check.c +++ b/fec/src/check.c @@ -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)) - err(s->c,n->loc,"initializer type mismatch"); + !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) diff --git a/fec/tests/optional/badcatch.fe b/fec/tests/optional/badcatch.fe index d6b2bdb..97ed75c 100644 --- a/fec/tests/optional/badcatch.fe +++ b/fec/tests/optional/badcatch.fe @@ -1,4 +1,4 @@ -// ERROR:14:catch +// ERROR:13:catch unit badcatch; error E { diff --git a/fec/tests/own/badarg.fe b/fec/tests/own/badarg.fe index 355fb9c..7e50114 100644 --- a/fec/tests/own/badarg.fe +++ b/fec/tests/own/badarg.fe @@ -1,4 +1,4 @@ -// ERROR:8:self +// ERROR:8:derived from a parameter unit badarg; struct Box { diff --git a/fec/tests/own/badbrmov.fe b/fec/tests/own/badbrmov.fe index 7dbb11b..f07825d 100644 --- a/fec/tests/own/badbrmov.fe +++ b/fec/tests/own/badbrmov.fe @@ -1,4 +1,4 @@ -// ERROR:9:move +// ERROR:8:move unit badbrmov; fn bad(p: ^i32, consume: bool) -> void { diff --git a/fec/tests/own/badloop.fe b/fec/tests/own/badloop.fe index fed8c0f..1cb6a4f 100644 --- a/fec/tests/own/badloop.fe +++ b/fec/tests/own/badloop.fe @@ -1,4 +1,4 @@ -// ERROR:8:move +// ERROR:6:move unit badloop; fn bad(p: ^i32, again: bool) -> void {