Skip to content

Issue "'{0}' declarations can only be declared inside a block." for block-scoped variables in presence of parse errors #61824

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52836,7 +52836,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
blockScopeKind === NodeFlags.Using ? "using" :
blockScopeKind === NodeFlags.AwaitUsing ? "await using" :
Debug.fail("Unknown BlockScope flag");
return grammarErrorOnNode(node, Diagnostics._0_declarations_can_only_be_declared_inside_a_block, keyword);
error(node, Diagnostics._0_declarations_can_only_be_declared_inside_a_block, keyword);
}
}
}
Expand Down Expand Up @@ -52892,7 +52892,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function grammarErrorOnNode(node: Node, message: DiagnosticMessage, ...args: DiagnosticArguments): boolean {
const sourceFile = getSourceFileOfNode(node);
if (!hasParseDiagnostics(sourceFile)) {
diagnostics.add(createDiagnosticForNode(node, message, ...args));
error(node, message, ...args);
return true;
}
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
disallowedBlockScopedInPresenceOfParseErrors1.ts(5,5): error TS1156: 'const' declarations can only be declared inside a block.
disallowedBlockScopedInPresenceOfParseErrors1.ts(6,17): error TS2454: Variable 'e' is used before being assigned.
disallowedBlockScopedInPresenceOfParseErrors1.ts(8,1): error TS1128: Declaration or statement expected.
disallowedBlockScopedInPresenceOfParseErrors1.ts(12,5): error TS1156: 'let' declarations can only be declared inside a block.
disallowedBlockScopedInPresenceOfParseErrors1.ts(13,17): error TS2454: Variable 'e' is used before being assigned.
disallowedBlockScopedInPresenceOfParseErrors1.ts(15,1): error TS1128: Declaration or statement expected.
disallowedBlockScopedInPresenceOfParseErrors1.ts(21,5): error TS1156: 'using' declarations can only be declared inside a block.
disallowedBlockScopedInPresenceOfParseErrors1.ts(22,17): error TS2454: Variable 'e' is used before being assigned.
disallowedBlockScopedInPresenceOfParseErrors1.ts(24,1): error TS1128: Declaration or statement expected.
disallowedBlockScopedInPresenceOfParseErrors1.ts(30,5): error TS1156: 'await using' declarations can only be declared inside a block.
disallowedBlockScopedInPresenceOfParseErrors1.ts(31,17): error TS2454: Variable 'e' is used before being assigned.
disallowedBlockScopedInPresenceOfParseErrors1.ts(33,1): error TS1128: Declaration or statement expected.


==== disallowedBlockScopedInPresenceOfParseErrors1.ts (12 errors) ====
// https://github.com/microsoft/TypeScript/issues/61734

function f1() {
if (1 > 0)
const e = 3;
~~~~~~~~~~~~
!!! error TS1156: 'const' declarations can only be declared inside a block.
console.log(e);
~
!!! error TS2454: Variable 'e' is used before being assigned.
}
}
~
!!! error TS1128: Declaration or statement expected.

function f2() {
if (1 > 0)
let e = 3;
~~~~~~~~~~
!!! error TS1156: 'let' declarations can only be declared inside a block.
console.log(e);
~
!!! error TS2454: Variable 'e' is used before being assigned.
}
}
~
!!! error TS1128: Declaration or statement expected.

declare const resource: Disposable

function f3() {
if (1 > 0)
using e = resource;
~~~~~~~~~~~~~~~~~~~
!!! error TS1156: 'using' declarations can only be declared inside a block.
console.log(e);
~
!!! error TS2454: Variable 'e' is used before being assigned.
}
}
~
!!! error TS1128: Declaration or statement expected.

declare const asyncResource: AsyncDisposable

async function f4() {
if (1 > 0)
await using e = asyncResource;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS1156: 'await using' declarations can only be declared inside a block.
console.log(e);
~
!!! error TS2454: Variable 'e' is used before being assigned.
}
}
~
!!! error TS1128: Declaration or statement expected.

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//// [tests/cases/compiler/disallowedBlockScopedInPresenceOfParseErrors1.ts] ////

=== disallowedBlockScopedInPresenceOfParseErrors1.ts ===
// https://github.com/microsoft/TypeScript/issues/61734

function f1() {
>f1 : Symbol(f1, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 0, 0))

if (1 > 0)
const e = 3;
>e : Symbol(e, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 4, 9))

console.log(e);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>e : Symbol(e, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 4, 9))
}
}

function f2() {
>f2 : Symbol(f2, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 7, 1))

if (1 > 0)
let e = 3;
>e : Symbol(e, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 11, 7))

console.log(e);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>e : Symbol(e, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 11, 7))
}
}

declare const resource: Disposable
>resource : Symbol(resource, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 16, 13))
>Disposable : Symbol(Disposable, Decl(lib.esnext.disposable.d.ts, --, --))

function f3() {
>f3 : Symbol(f3, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 16, 34))

if (1 > 0)
using e = resource;
>e : Symbol(e, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 20, 9))
>resource : Symbol(resource, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 16, 13))

console.log(e);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>e : Symbol(e, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 20, 9))
}
}

declare const asyncResource: AsyncDisposable
>asyncResource : Symbol(asyncResource, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 25, 13))
>AsyncDisposable : Symbol(AsyncDisposable, Decl(lib.esnext.disposable.d.ts, --, --))

async function f4() {
>f4 : Symbol(f4, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 25, 44))

if (1 > 0)
await using e = asyncResource;
>e : Symbol(e, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 29, 15))
>asyncResource : Symbol(asyncResource, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 25, 13))

console.log(e);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>e : Symbol(e, Decl(disallowedBlockScopedInPresenceOfParseErrors1.ts, 29, 15))
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
//// [tests/cases/compiler/disallowedBlockScopedInPresenceOfParseErrors1.ts] ////

=== disallowedBlockScopedInPresenceOfParseErrors1.ts ===
// https://github.com/microsoft/TypeScript/issues/61734

function f1() {
>f1 : () => void
> : ^^^^^^^^^^

if (1 > 0)
>1 > 0 : boolean
> : ^^^^^^^
>1 : 1
> : ^
>0 : 0
> : ^

const e = 3;
>e : 3
> : ^
>3 : 3
> : ^

console.log(e);
>console.log(e) : void
> : ^^^^
>console.log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>console : Console
> : ^^^^^^^
>log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>e : 3
> : ^
}
}

function f2() {
>f2 : () => void
> : ^^^^^^^^^^

if (1 > 0)
>1 > 0 : boolean
> : ^^^^^^^
>1 : 1
> : ^
>0 : 0
> : ^

let e = 3;
>e : number
> : ^^^^^^
>3 : 3
> : ^

console.log(e);
>console.log(e) : void
> : ^^^^
>console.log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>console : Console
> : ^^^^^^^
>log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>e : number
> : ^^^^^^
}
}

declare const resource: Disposable
>resource : Disposable
> : ^^^^^^^^^^

function f3() {
>f3 : () => void
> : ^^^^^^^^^^

if (1 > 0)
>1 > 0 : boolean
> : ^^^^^^^
>1 : 1
> : ^
>0 : 0
> : ^

using e = resource;
>e : Disposable
> : ^^^^^^^^^^
>resource : Disposable
> : ^^^^^^^^^^

console.log(e);
>console.log(e) : void
> : ^^^^
>console.log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>console : Console
> : ^^^^^^^
>log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>e : Disposable
> : ^^^^^^^^^^
}
}

declare const asyncResource: AsyncDisposable
>asyncResource : AsyncDisposable
> : ^^^^^^^^^^^^^^^

async function f4() {
>f4 : () => Promise<void>
> : ^^^^^^^^^^^^^^^^^^^

if (1 > 0)
>1 > 0 : boolean
> : ^^^^^^^
>1 : 1
> : ^
>0 : 0
> : ^

await using e = asyncResource;
>e : AsyncDisposable
> : ^^^^^^^^^^^^^^^
>asyncResource : AsyncDisposable
> : ^^^^^^^^^^^^^^^

console.log(e);
>console.log(e) : void
> : ^^^^
>console.log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>console : Console
> : ^^^^^^^
>log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>e : AsyncDisposable
> : ^^^^^^^^^^^^^^^
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// @strict: true
// @target: esnext
// @noEmit: true

// https://github.com/microsoft/TypeScript/issues/61734

function f1() {
if (1 > 0)
const e = 3;
console.log(e);
}
}

function f2() {
if (1 > 0)
let e = 3;
console.log(e);
}
}

declare const resource: Disposable

function f3() {
if (1 > 0)
using e = resource;
console.log(e);
}
}

declare const asyncResource: AsyncDisposable

async function f4() {
if (1 > 0)
await using e = asyncResource;
console.log(e);
}
}