Improve entry main diagnostics
This commit is contained in:
parent
bcfc8d7b68
commit
cda20bc895
26
.llm/BETA_4_LANGUAGE_USABILITY.md
Normal file
26
.llm/BETA_4_LANGUAGE_USABILITY.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Beta 4 Language Usability
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This post-`1.0.0-beta.3` slice reduces friction in ordinary project use
|
||||||
|
without changing the typed core or claiming new syntax stability.
|
||||||
|
|
||||||
|
## Current Work
|
||||||
|
|
||||||
|
- Improve project/workspace build and run entry diagnostics.
|
||||||
|
- Keep the accepted entry contract unchanged: `(fn main () -> i32 ...)`.
|
||||||
|
- Use precise diagnostic codes for missing and invalid entry `main` functions.
|
||||||
|
|
||||||
|
## Acceptance Gates
|
||||||
|
|
||||||
|
- `cargo test --test project_mode entry_main`
|
||||||
|
- `cargo fmt --check`
|
||||||
|
- `git diff --check`
|
||||||
|
|
||||||
|
## Deferrals
|
||||||
|
|
||||||
|
- No implicit `main` return conversions.
|
||||||
|
- No argument-taking `main`.
|
||||||
|
- No async, package registry, or stable ABI/layout promises.
|
||||||
|
- Broader type aliases, match diagnostics, and destructuring remain candidate
|
||||||
|
follow-up items in the same language usability roadmap lane.
|
||||||
@ -4156,8 +4156,11 @@ fn add_entry_wrapper(
|
|||||||
else {
|
else {
|
||||||
diagnostics.push(Diagnostic::new(
|
diagnostics.push(Diagnostic::new(
|
||||||
&entry_module.file,
|
&entry_module.file,
|
||||||
"MissingImport",
|
"ProjectEntryMainMissing",
|
||||||
format!("entry module `{}` has no `main` function", manifest.entry),
|
format!(
|
||||||
|
"entry module `{}` has no `main` function; build/run require `(fn main () -> i32 ...)`",
|
||||||
|
manifest.entry
|
||||||
|
),
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@ -4166,8 +4169,12 @@ fn add_entry_wrapper(
|
|||||||
diagnostics.push(
|
diagnostics.push(
|
||||||
Diagnostic::new(
|
Diagnostic::new(
|
||||||
&entry_module.file,
|
&entry_module.file,
|
||||||
"MissingImport",
|
"ProjectEntryMainInvalidSignature",
|
||||||
"project entry `main` must have no parameters and return `i32`",
|
format!(
|
||||||
|
"project entry `main` must have signature `(fn main () -> i32 ...)`; found {} parameter(s) and return `{}`",
|
||||||
|
entry_function.params.len(),
|
||||||
|
entry_function.return_type
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.with_span(entry_function.span),
|
.with_span(entry_function.span),
|
||||||
);
|
);
|
||||||
@ -4229,9 +4236,9 @@ fn add_workspace_entry_wrapper(
|
|||||||
else {
|
else {
|
||||||
diagnostics.push(Diagnostic::new(
|
diagnostics.push(Diagnostic::new(
|
||||||
&entry_module.file,
|
&entry_module.file,
|
||||||
"MissingImport",
|
"WorkspaceEntryMainMissing",
|
||||||
format!(
|
format!(
|
||||||
"entry module `{}` in package `{}` has no `main` function",
|
"entry module `{}` in package `{}` has no `main` function; build/run require `(fn main () -> i32 ...)`",
|
||||||
package.manifest.entry, package.manifest.name
|
package.manifest.entry, package.manifest.name
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
@ -4242,8 +4249,12 @@ fn add_workspace_entry_wrapper(
|
|||||||
diagnostics.push(
|
diagnostics.push(
|
||||||
Diagnostic::new(
|
Diagnostic::new(
|
||||||
&entry_module.file,
|
&entry_module.file,
|
||||||
"MissingImport",
|
"WorkspaceEntryMainInvalidSignature",
|
||||||
"workspace entry `main` must have no parameters and return `i32`",
|
format!(
|
||||||
|
"workspace entry `main` must have signature `(fn main () -> i32 ...)`; found {} parameter(s) and return `{}`",
|
||||||
|
entry_function.params.len(),
|
||||||
|
entry_function.return_type
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.with_span(entry_function.span),
|
.with_span(entry_function.span),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -587,6 +587,68 @@ fn workspace_build_requires_one_entry_package() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn workspace_build_reports_entry_main_contract() {
|
||||||
|
let missing_main = write_workspace(
|
||||||
|
"workspace-missing-entry-main",
|
||||||
|
"[workspace]\nmembers = [\"packages/app\"]\n",
|
||||||
|
&[WorkspacePackageSpec {
|
||||||
|
member: "packages/app",
|
||||||
|
manifest: "[package]\nname = \"app\"\nversion = \"0.1.0\"\n",
|
||||||
|
modules: &[("main", "(module main)\n\n(test \"ok\"\n true)\n")],
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
let missing_binary = unique_path("workspace-missing-entry-main-bin");
|
||||||
|
let missing_output = run_glagol([
|
||||||
|
"build".as_ref(),
|
||||||
|
"-o".as_ref(),
|
||||||
|
missing_binary.as_os_str(),
|
||||||
|
missing_main.as_os_str(),
|
||||||
|
]);
|
||||||
|
assert_exit_code("workspace missing entry main", &missing_output, 1);
|
||||||
|
assert_stderr_contains(
|
||||||
|
"workspace missing entry main",
|
||||||
|
&missing_output,
|
||||||
|
"WorkspaceEntryMainMissing",
|
||||||
|
);
|
||||||
|
assert_stderr_contains(
|
||||||
|
"workspace missing entry main",
|
||||||
|
&missing_output,
|
||||||
|
"build/run require `(fn main () -> i32 ...)`",
|
||||||
|
);
|
||||||
|
|
||||||
|
let bad_signature = write_workspace(
|
||||||
|
"workspace-bad-entry-main",
|
||||||
|
"[workspace]\nmembers = [\"packages/app\"]\n",
|
||||||
|
&[WorkspacePackageSpec {
|
||||||
|
member: "packages/app",
|
||||||
|
manifest: "[package]\nname = \"app\"\nversion = \"0.1.0\"\n",
|
||||||
|
modules: &[(
|
||||||
|
"main",
|
||||||
|
"(module main)\n\n(fn main () -> string\n \"bad\")\n",
|
||||||
|
)],
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
let bad_binary = unique_path("workspace-bad-entry-main-bin");
|
||||||
|
let bad_output = run_glagol([
|
||||||
|
"build".as_ref(),
|
||||||
|
"-o".as_ref(),
|
||||||
|
bad_binary.as_os_str(),
|
||||||
|
bad_signature.as_os_str(),
|
||||||
|
]);
|
||||||
|
assert_exit_code("workspace bad entry main", &bad_output, 1);
|
||||||
|
assert_stderr_contains(
|
||||||
|
"workspace bad entry main",
|
||||||
|
&bad_output,
|
||||||
|
"WorkspaceEntryMainInvalidSignature",
|
||||||
|
);
|
||||||
|
assert_stderr_contains(
|
||||||
|
"workspace bad entry main",
|
||||||
|
&bad_output,
|
||||||
|
"found 0 parameter(s) and return `string`",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn workspace_package_boundaries_are_diagnostics() {
|
fn workspace_package_boundaries_are_diagnostics() {
|
||||||
let missing = write_workspace(
|
let missing = write_workspace(
|
||||||
@ -1244,7 +1306,16 @@ fn project_build_requires_entry_main_contract() {
|
|||||||
missing_main.as_os_str(),
|
missing_main.as_os_str(),
|
||||||
]);
|
]);
|
||||||
assert_exit_code("missing entry main", &missing_output, 1);
|
assert_exit_code("missing entry main", &missing_output, 1);
|
||||||
assert_stderr_contains("missing entry main", &missing_output, "MissingImport");
|
assert_stderr_contains(
|
||||||
|
"missing entry main",
|
||||||
|
&missing_output,
|
||||||
|
"ProjectEntryMainMissing",
|
||||||
|
);
|
||||||
|
assert_stderr_contains(
|
||||||
|
"missing entry main",
|
||||||
|
&missing_output,
|
||||||
|
"build/run require `(fn main () -> i32 ...)`",
|
||||||
|
);
|
||||||
|
|
||||||
let bad_signature = write_project(
|
let bad_signature = write_project(
|
||||||
"bad-main-signature",
|
"bad-main-signature",
|
||||||
@ -1259,7 +1330,16 @@ fn project_build_requires_entry_main_contract() {
|
|||||||
bad_signature.as_os_str(),
|
bad_signature.as_os_str(),
|
||||||
]);
|
]);
|
||||||
assert_exit_code("bad entry main signature", &bad_output, 1);
|
assert_exit_code("bad entry main signature", &bad_output, 1);
|
||||||
assert_stderr_contains("bad entry main signature", &bad_output, "MissingImport");
|
assert_stderr_contains(
|
||||||
|
"bad entry main signature",
|
||||||
|
&bad_output,
|
||||||
|
"ProjectEntryMainInvalidSignature",
|
||||||
|
);
|
||||||
|
assert_stderr_contains(
|
||||||
|
"bad entry main signature",
|
||||||
|
&bad_output,
|
||||||
|
"found 1 parameter(s) and return `i32`",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -113,6 +113,10 @@ Candidate features:
|
|||||||
Why fourth: these features improve real Slovo code while keeping generics and
|
Why fourth: these features improve real Slovo code while keeping generics and
|
||||||
traits deferred until the core has more feedback.
|
traits deferred until the core has more feedback.
|
||||||
|
|
||||||
|
Started on `main` after `1.0.0-beta.3`: project/workspace build and run entry
|
||||||
|
diagnostics now use entry-specific codes and explicitly show the required
|
||||||
|
`(fn main () -> i32 ...)` contract.
|
||||||
|
|
||||||
### 5. Package And Workspace Discipline
|
### 5. Package And Workspace Discipline
|
||||||
|
|
||||||
Goal: make multi-package local development predictable before remote registry
|
Goal: make multi-package local development predictable before remote registry
|
||||||
|
|||||||
@ -10,7 +10,11 @@ integration/readiness release, not the first real beta.
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
No unreleased changes yet.
|
- Project build/run entry diagnostics now use entry-specific codes:
|
||||||
|
`ProjectEntryMainMissing`, `ProjectEntryMainInvalidSignature`,
|
||||||
|
`WorkspaceEntryMainMissing`, and `WorkspaceEntryMainInvalidSignature`.
|
||||||
|
Messages now spell out the required `(fn main () -> i32 ...)` contract and
|
||||||
|
include the found parameter count and return type for invalid signatures.
|
||||||
|
|
||||||
## 1.0.0-beta.3
|
## 1.0.0-beta.3
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user