"Debug Failure. False expression:" with my stack trace in 0.9.5

Topics: General
Dec 6, 2013 at 4:15 PM
Notice that there's no actual message. I figure this is a bug in 0.9.5, but how can I find what it's choking on and work around it?

I had to make code changes to upgrade to 0.9.5 (from 0.9.1 I think?) by Visual Studio (2012)-integrated tooling's error reporting, but now those are all resolved.

Thanks!
> node "tsc.js" --out app.js --target ES5 appMainFileOfMany.ts

tsc.js:950
                throw new Error("Debug Failure. False expression: " + message
                      ^
Error: Debug Failure. False expression:
    at Function.Debug.assert (tsc.js:950:23)
    at PullTypeResolver.resolveDeclaredSymbolWorker (tsc.js:39470:38)
    at PullTypeResolver.resolveDeclaredSymbol (tsc.js:39432:25)
    at PullTypeResolver.resolveNameExpression (tsc.js:43770:18)
    at PullTypeResolver.resolveAST (tsc.js:43338:37)
    at PullTypeResolver.resolveSimplePropertyAssignment (tsc.js:44775:25)
    at PullTypeResolver.resolveAST (tsc.js:43329:33)
    at PullTypeResolver.resolveDeclaredSymbolWorker (tsc.js:39471:47)
    at PullTypeResolver.resolveDeclaredSymbol (tsc.js:39432:25)
    at PullTypeResolver.sourceMembersAreRelatableToTargetMembers (tsc.js:46840:22)
    at PullTypeResolver.sourceIsRelatableToTarget (tsc.js:46809:46)
    at PullTypeResolver.sourceIsRelatableToTarget (tsc.js:46764:39)
    at PullTypeResolver.sourceIsRelatableToTargetInEnclosingTypes (tsc.js:46659:25)
    at PullTypeResolver.signatureIsRelatableToTarget (tsc.js:47242:27)
    at PullTypeResolver.signatureGroupIsRelatableToTarget (tsc.js:47191:30)
    at PullTypeResolver.sourceCallSignaturesAreRelatableToTargetCallSignatures (tsc.js:47050:27)
    at PullTypeResolver.sourceIsRelatableToTarget (tsc.js:46814:23)
    at PullTypeResolver.sourceIsSubtypeOfTarget (tsc.js:46592:25)
    at PullTypeResolver.overloadIsApplicableForArgumentHelper (tsc.js:47485:57)
    at PullTypeResolver.overloadIsApplicableForAnyFunctionExpressionArgument (tsc.js:47433:44)
    at PullTypeResolver.overloadIsApplicableForArgument (tsc.js:47408:29)
    at PullTypeResolver.overloadIsApplicable (tsc.js:47387:52)
    at PullTypeResolver.resolveOverloads (tsc.js:47320:42)
    at PullTypeResolver.computeInvocationExpressionSymbol (tsc.js:45665:34)
    at PullTypeResolver.resolveInvocationExpression (tsc.js:45413:31)
    at PullTypeResolver.resolveAST (tsc.js:43394:33)
    at PullTypeResolver.computeInvocationExpressionSymbol (tsc.js:45717:26)
    at PullTypeResolver.resolveInvocationExpression (tsc.js:45413:31)
    at PullTypeResolver.resolveAST (tsc.js:43394:33)
    at PullTypeResolver.typeCheckCastExpression (tsc.js:46162:33)
    at PullTypeResolver.resolveCastExpression (tsc.js:46152:22)
    at PullTypeResolver.resolveAST (tsc.js:43400:33)
    at PullTypeResolver.resolveEqualsValueClause (tsc.js:40927:25)
    at PullTypeResolver.resolveAST (tsc.js:43314:33)
    at PullTypeResolver.resolveAndTypeCheckVariableDeclaratorOrParameterInitExpr (tsc.js:41095:39)
    at PullTypeResolver.resolveVariableDeclaratorOrParameterOrEnumElement (tsc.js:40967:30)
    at PullTypeResolver.resolveVariableDeclarator (tsc.js:40894:25)
    at PullTypeResolver.resolveAST (tsc.js:43299:33)
    at PullTypeResolver.resolveSeparatedList (tsc.js:42424:26)
    at PullTypeResolver.resolveAST (tsc.js:43275:33)
    at PullTypeResolver.resolveVariableDeclarationList (tsc.js:42822:22)
    at PullTypeResolver.resolveAST (tsc.js:43293:33)
    at PullTypeResolver.resolveVariableStatement (tsc.js:42813:22)
    at PullTypeResolver.resolveAST (tsc.js:43538:33)
    at PullTypeResolver.resolveList (tsc.js:42412:26)
    at PullTypeResolver.resolveAST (tsc.js:43272:33)
    at PullTypeResolver.resolveBlock (tsc.js:42804:22)
    at PullTypeResolver.resolveAST (tsc.js:43535:33)
    at PullTypeResolver.typeCheckFunctionDeclaration (tsc.js:41575:18)
    at PullTypeResolver.resolveFunctionDeclaration (tsc.js:42076:22)
    at PullTypeResolver.resolveMemberFunctionDeclaration (tsc.js:41696:25)
    at PullTypeResolver.resolveAST (tsc.js:43361:33)
    at PullTypeResolver.resolveDeclaredSymbolWorker (tsc.js:39471:47)
    at PullTypeResolver.resolveDeclaredSymbol (tsc.js:39432:25)
    at PullTypeResolver.resolveDottedNameExpression (tsc.js:43919:18)
    at PullTypeResolver.resolveMemberAccessExpression (tsc.js:43903:25)
    at PullTypeResolver.resolveAST (tsc.js:43342:33)
    at PullTypeResolver.computeInvocationExpressionSymbol (tsc.js:45467:37)
    at PullTypeResolver.resolveInvocationExpression (tsc.js:45413:31)
    at PullTypeResolver.resolveAST (tsc.js:43394:33)
    at PullTypeResolver.resolveExpressionStatement (tsc.js:45400:22)
    at PullTypeResolver.resolveAST (tsc.js:43505:33)
    at PullTypeResolver.resolveList (tsc.js:42412:26)
    at PullTypeResolver.resolveAST (tsc.js:43272:33)
    at PullTypeResolver.resolveBlock (tsc.js:42804:22)
    at PullTypeResolver.resolveAST (tsc.js:43535:33)
    at PullTypeResolver.typeCheckAnyFunctionExpression (tsc.js:44458:22)
    at PullTypeResolver.resolveAnyFunctionExpression (tsc.js:44425:22)
    at PullTypeResolver.resolveParenthesizedArrowFunctionExpression (tsc.js:41724:25)
    at PullTypeResolver.resolveAST (tsc.js:43382:33)
    at PullTypeResolver.computeInvocationExpressionSymbol (tsc.js:45717:26)
    at PullTypeResolver.resolveInvocationExpression (tsc.js:45413:31)
    at PullTypeResolver.resolveAST (tsc.js:43394:33)
    at PullTypeResolver.resolveExpressionStatement (tsc.js:45400:22)
    at PullTypeResolver.resolveAST (tsc.js:43505:33)
    at PullTypeResolver.resolveList (tsc.js:42412:26)
    at PullTypeResolver.resolveAST (tsc.js:43272:33)
    at PullTypeResolver.resolveBlock (tsc.js:42804:22)
    at PullTypeResolver.resolveAST (tsc.js:43535:33)
    at PullTypeResolver.typeCheckConstructorDeclaration (tsc.js:41509:18)
    at PullTypeResolver.resolveConstructorDeclaration (tsc.js:41823:22)
    at PullTypeResolver.resolveAST (tsc.js:43348:33)
    at PullTypeResolver.resolveList (tsc.js:42412:26)
    at PullTypeResolver.resolveAST (tsc.js:43272:33)
    at PullTypeResolver.typeCheckClassDeclaration (tsc.js:39964:18)
    at PullTypeResolver.resolveClassDeclaration (tsc.js:39939:22)
    at PullTypeResolver.resolveAST (tsc.js:43290:33)
    at PullTypeResolver.resolveList (tsc.js:42412:26)
    at PullTypeResolver.resolveAST (tsc.js:43272:33)
    at PullTypeResolver.typeCheckSingleModuleDeclaration (tsc.js:39665:22)
    at PullTypeResolver.typeCheckModuleDeclaration (tsc.js:39656:26)
    at PullTypeResolver.typeCheckAST (tsc.js:43587:26)
    at PullTypeResolver.resolveAST (tsc.js:43256:22)
    at PullTypeResolver.resolveList (tsc.js:42412:26)
    at PullTypeResolver.resolveAST (tsc.js:43272:33)
    at PullTypeResolver.resolveSourceUnit (tsc.js:39508:18)
    at PullTypeResolver.resolveAST (tsc.js:43278:33)
    at Function.PullTypeResolver.typeCheck (tsc.js:47798:26)
    at TypeScriptCompiler.getSemanticDiagnostics (tsc.js:53673:41)
    at CompilerIterator.moveNextSemanticsPhase (tsc.js:54246:45)
    at CompilerIterator.moveNextInternal (tsc.js:54196:33)
    at CompilerIterator.moveNext (tsc.js:54171:25)
    at BatchCompiler.compile (tsc.js:60389:20)
    at BatchCompiler.batchCompile (tsc.js:60268:22)
    at TypeScript (tsc.js:60897:11)
    at Object.<anonymous> (tsc.js:60898:3)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:901:3
Coordinator
Dec 6, 2013 at 5:02 PM
The assert comes from here:
                // If our decl points at a single name of a module, then just resolve that individual module.
                var enclosingModule = getEnclosingModuleDeclaration(ast);
                var resolvedSymbol: PullSymbol;
                if (isAnyNameOfModule(enclosingModule, ast)) {
                    resolvedSymbol = this.resolveSingleModuleDeclaration(enclosingModule, ast, context);
                }
                else if (ast.kind() === SyntaxKind.SourceUnit && decl.kind === PullElementKind.DynamicModule) {
                    // Otherwise, if we have a decl for the top level external module, then just resolve that
                    // specific module.
                    resolvedSymbol = this.resolveModuleSymbol(<PullContainerSymbol>decl.getSymbol(), context, /*moduleDeclAST:*/ null, /*moduleNameAST:*/ null, <SourceUnit>ast);
                }
                else {
                    // This assert is here to catch potential stack overflows. There have been infinite recursions resulting
                    // from one of these decls pointing to a name expression.
                    Debug.assert(ast.kind() !== SyntaxKind.IdentifierName && ast.kind() !== SyntaxKind.MemberAccessExpression);
                    var resolvedSymbol: PullSymbol = this.resolveAST(ast, /*isContextuallyTyped*/false, context);
                }
I've asked Joe to figure out a few theories on what might be going on so we can try to isolate a repro.
Developer
Dec 6, 2013 at 6:21 PM
Hey Amiristrator,

Based on the callstack and the assert in question, we have a theory about what may be going wrong.

We think that you have some snippet of code in your project like so:

Foo ( XXX => <stuff> )

i.e. you're calling some function/method, and you're passing in a single parameter arrow function to it as one of the arguments.


What we need is the code a few lines before and after this function call, as well as the signature of the method (or group of methods) that are being called.

To help figure this, you'll likely need to run under a debugger and trap the assert when it happens. When it does, go up one stack frame to:
PullTypeResolver.resolveDeclaredSymbolWorker (tsc.js:39470:38)

And take a look at the "ast" variable that we're checking. By drilling into it in the debugger, you should be able to get the "name" of the ast node (i.e. "XXX") in teh example above. Hopefully that name is unique enough to tell you which arrow function is the one we're having a problem with. Once you have that, you can provide hte surrounding context, as well as the signatures of the functions being called, and that will hopefully be enough for us to go off of.
Coordinator
Dec 6, 2013 at 6:24 PM
Alternatively if you want to post a zip file on the issue tracker or via email (ryanca@microsoft.com) we'd be happy to take a look.
Dec 6, 2013 at 7:20 PM
OK, well for the Achievements, I had already hacked tsc.js to spit out the file name and offending symbol.

I've narrowed it down to a basic example telling us that 'p' is of the unexpected ast.kind() == 11 / IdentifierName /
var values =
    Array.prototype.concat.apply([], (<string[]>[]).map(a =>
        (<number[]>[]).map(p => {
            return { A: a, P: p }; // fails on this `p`, but not in `[a, p]`
        })));
One interesting note is that when I test it at the global scope, the symbol name is formatted as 'symbol: type'
But when it's in the original location buried in a callback in a ctor of a class in a module, it only shows the 'symbol'
And if I don't cast the arrays to a particular array (here) then I get 'p: undefined' as the symbol. As written it shows 'p: number'.

Is that enough? Is there a workaround so I can get mine to compile?

Thanks!
Developer
Dec 6, 2013 at 7:28 PM
Edited Dec 6, 2013 at 7:31 PM
We haven't looked deeply at it yet. But, your workaround may be to use (a) =>... and (p) => ... (i.e. parenthesize the parameter names).

We also have a smaller repro. Thanks so much for your help!
Coordinator
Dec 6, 2013 at 7:31 PM
Simplified the best we can get it:
// Errors
[].map(() => [].map(p => ({ X: p })));
// Workaround: Put parentheses around the parameters
[].map(() => [].map((p) => ({ X: p })));
Thanks for tracking down the offending line!
Dec 6, 2013 at 7:41 PM
Yes, that works for me. Sweet! Thanks.
Dec 19, 2013 at 6:12 AM
I was using the
p => ({ X: p }) 
syntax as well, and attempted to first change it to
p => { 
   return { 
      X: p
   }
}
in the hope that it would resolve the problem. However this didn't work. I then went through ALL my code in my project and changed as many instances of x => to (x) => as possible. It now builds successfully.