From 74d09983a1aff12cab84b89ca6fa52a3fe1f62a4 Mon Sep 17 00:00:00 2001 From: camc314 <18101008+camc314@users.noreply.github.com> Date: Sun, 25 Jan 2026 18:00:55 +0000 Subject: [PATCH] fix(semantic): update error msg for multiple `default` cases in switch stmt (#18526) --- crates/oxc_semantic/src/checker/javascript.rs | 5 ++++- crates/oxc_semantic/src/diagnostics.rs | 12 ++++++++++++ tasks/coverage/snapshots/parser_babel.snap | 12 ++++++------ tasks/coverage/snapshots/parser_test262.snap | 6 +++--- .../coverage/snapshots/parser_typescript.snap | 18 +++++++++--------- 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/crates/oxc_semantic/src/checker/javascript.rs b/crates/oxc_semantic/src/checker/javascript.rs index d03be9aad0495..2640efe736098 100644 --- a/crates/oxc_semantic/src/checker/javascript.rs +++ b/crates/oxc_semantic/src/checker/javascript.rs @@ -733,7 +733,10 @@ pub fn check_switch_statement<'a>(stmt: &SwitchStatement<'a>, ctx: &SemanticBuil for case in &stmt.cases { if case.test.is_none() { if let Some(previous_span) = previous_default { - ctx.error(diagnostics::redeclaration("default", previous_span, case.span)); + ctx.error(diagnostics::switch_stmt_cannot_have_multiple_default_case( + previous_span, + case.span, + )); break; } previous_default.replace(case.span); diff --git a/crates/oxc_semantic/src/diagnostics.rs b/crates/oxc_semantic/src/diagnostics.rs index 2589bc4d61359..8bc4a54af71e0 100644 --- a/crates/oxc_semantic/src/diagnostics.rs +++ b/crates/oxc_semantic/src/diagnostics.rs @@ -423,3 +423,15 @@ pub fn ts_export_assignment_cannot_be_used_with_other_exports(span: Span) -> Oxc .with_label(span) .with_help("If you want to use `export =`, remove other `export`s and put all of them to the right hand value of `export =`. If you want to use `export`s, remove `export =` statement.") } + +#[cold] +pub fn switch_stmt_cannot_have_multiple_default_case( + first_default: Span, + other_default: Span, +) -> OxcDiagnostic { + ts_error("1113", "A 'default' clause cannot appear more than once in a 'switch' statement.") + .with_labels(vec![ + first_default.label("First 'default' clause is here."), + other_default.label("Another 'default' clause cannot appear here."), + ]) +} diff --git a/tasks/coverage/snapshots/parser_babel.snap b/tasks/coverage/snapshots/parser_babel.snap index 3429c3a2e0fca..595e33ff50799 100644 --- a/tasks/coverage/snapshots/parser_babel.snap +++ b/tasks/coverage/snapshots/parser_babel.snap @@ -1716,12 +1716,12 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ─ ╰──── - × Identifier `default` has already been declared + × TS(1113): A 'default' clause cannot appear more than once in a 'switch' statement. ╭─[babel/packages/babel-parser/test/fixtures/core/uncategorised/427/input.js:1:14] 1 │ switch (c) { default: default: } · ────┬─── ────┬─── - · │ ╰── It can not be redeclared here - · ╰── `default` has already been declared here + · │ ╰── Another 'default' clause cannot appear here. + · ╰── First 'default' clause is here. ╰──── × Unexpected token @@ -11147,12 +11147,12 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc ╰──── help: Wrap this declaration in a block statement - × Identifier `default` has already been declared + × TS(1113): A 'default' clause cannot appear more than once in a 'switch' statement. ╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0143/input.js:1:14] 1 │ switch (c) { default: default: } · ────┬─── ────┬─── - · │ ╰── It can not be redeclared here - · ╰── `default` has already been declared here + · │ ╰── Another 'default' clause cannot appear here. + · ╰── First 'default' clause is here. ╰──── × Unexpected token diff --git a/tasks/coverage/snapshots/parser_test262.snap b/tasks/coverage/snapshots/parser_test262.snap index 58d1a4b73b154..cca3f1e83e1fa 100644 --- a/tasks/coverage/snapshots/parser_test262.snap +++ b/tasks/coverage/snapshots/parser_test262.snap @@ -38454,17 +38454,17 @@ Negative Passed: 4581/4581 (100.00%) 22 │ } ╰──── - × Identifier `default` has already been declared + × TS(1113): A 'default' clause cannot appear more than once in a 'switch' statement. ╭─[test262/test/language/statements/switch/S12.11_A2_T1.js:22:5] 21 │ result += 2; 22 │ ╭─▶ default: 23 │ │ result += 32; 24 │ ├─▶ break; - · ╰──── `default` has already been declared here + · ╰──── First 'default' clause is here. 25 │ ╭─▶ default: 26 │ │ result += 32; 27 │ ├─▶ break; - · ╰──── It can not be redeclared here + · ╰──── Another 'default' clause cannot appear here. 28 │ } ╰──── diff --git a/tasks/coverage/snapshots/parser_typescript.snap b/tasks/coverage/snapshots/parser_typescript.snap index 48b97d58b5c50..27848e7704813 100644 --- a/tasks/coverage/snapshots/parser_typescript.snap +++ b/tasks/coverage/snapshots/parser_typescript.snap @@ -11474,39 +11474,39 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/Va 28 │ default: default: ╰──── - × Identifier `default` has already been declared + × TS(1113): A 'default' clause cannot appear more than once in a 'switch' statement. ╭─[typescript/tests/cases/compiler/switchStatementsWithMultipleDefaults.ts:6:5] 5 │ case 2: 6 │ ╭─▶ default: // No issues. 7 │ ├─▶ break; - · ╰──── `default` has already been declared here + · ╰──── First 'default' clause is here. 8 │ default: // Error; second 'default' clause. · ────┬─── - · ╰── It can not be redeclared here + · ╰── Another 'default' clause cannot appear here. 9 │ default: // Error; third 'default' clause. ╰──── - × Identifier `default` has already been declared + × TS(1113): A 'default' clause cannot appear more than once in a 'switch' statement. ╭─[typescript/tests/cases/compiler/switchStatementsWithMultipleDefaults.ts:19:13] 18 │ switch (x * x) { 19 │ default: // No issues. · ────┬─── - · ╰── `default` has already been declared here + · ╰── First 'default' clause is here. 20 │ ╭─▶ default: // Error; second 'default' clause. 21 │ ├─▶ break; - · ╰──── It can not be redeclared here + · ╰──── Another 'default' clause cannot appear here. 22 │ case 10000: ╰──── - × Identifier `default` has already been declared + × TS(1113): A 'default' clause cannot appear more than once in a 'switch' statement. ╭─[typescript/tests/cases/compiler/switchStatementsWithMultipleDefaults1.ts:6:9] 5 │ case 2: 6 │ ╭─▶ default: // No issues. 7 │ ├─▶ break; - · ╰──── `default` has already been declared here + · ╰──── First 'default' clause is here. 8 │ default: // Error; second 'default' clause. · ────┬─── - · ╰── It can not be redeclared here + · ╰── Another 'default' clause cannot appear here. 9 │ default: // Error; third 'default' clause. ╰────