Fable: Babel: "You must pass a scope and parentPath unless traversing a Program/File."

Created on 19 Oct 2016  路  6Comments  路  Source: fable-compiler/Fable

Description

The following program is failing to compile with the following error:

ERROR: C:/D/temp/fable-issue/Main.js: You must pass a scope and parentPath unless traversing a Program/File. Instead of that you tried to traverse a "Identifier" node without passing scope and parentPath.
Error: C:/D/temp/fable-issue/Main.js: You must pass a scope and parentPath unless traversing a Program/File. Instead of that you tried to traverse a "Identifier" node without passing scope and parentPath.
    at traverse (C:\D\temp\fable-issue\node_modules\babel-traverse\lib\index.js:73:13)
    at File.buildCodeFrameError (C:\D\temp\fable-issue\node_modules\babel-core\lib\transformation\file\index.js:441:35)
    at Scope.checkBlockScopedCollisions (C:\D\temp\fable-issue\node_modules\babel-traverse\lib\scope\index.js:397:27)
    at Scope.registerBinding (C:\D\temp\fable-issue\node_modules\babel-traverse\lib\scope\index.js:579:16)
    at Scope.registerDeclaration (C:\D\temp\fable-issue\node_modules\babel-traverse\lib\scope\index.js:483:14)
    at Object.BlockScoped (C:\D\temp\fable-issue\node_modules\babel-traverse\lib\scope\index.js:185:28)
    at Object.newFn (C:\D\temp\fable-issue\node_modules\babel-traverse\lib\visitors.js:318:17)
    at NodePath._call (C:\D\temp\fable-issue\node_modules\babel-traverse\lib\path\context.js:76:18)
    at NodePath.call (C:\D\temp\fable-issue\node_modules\babel-traverse\lib\path\context.js:44:14)
    at NodePath.visit (C:\D\temp\fable-issue\node_modules\babel-traverse\lib\path\context.js:105:12)

Repro steps

Command line: fable --projFile ./Main.fsx --verbose

// Main.fsx
open LanguagePrimitives

type Instruction = 
| Jmp = 0x40uy // 0100 0000
| Jsr = 0x60uy // 0110 0000

type Register =
| R0 = 0x00uy // 0000 0000

let InstructionMask    = 0b11110000uy
let RegisterMask       = 0b00000111uy

type Operand =
| NoOp
| Reg of Register
| Addr of uint16

type InstructionRegister = {
    mutable Data: byte array
    mutable SourceOperand: Operand
    mutable TargetOperand: Operand
}

type Registers = {
    R: uint16 array
    InstructionRegister: InstructionRegister
}

type Cpu = {
    Registers: Registers
}

let Execute cpu =
    let _r = cpu.Registers.R
    let _ir = cpu.Registers.InstructionRegister

    let firstOpCode = _ir.Data.[0]
    let instruction = firstOpCode &&& InstructionMask |> EnumOfValue
    let register = firstOpCode &&& RegisterMask

    match instruction with

// (*        // Comment/remove this block and the problem doesn't happen.
    | Instruction.Jmp ->
        match _ir.TargetOperand with
        | Addr address -> _r.[7] <- address
        | _ -> ()
// *)            

    | Instruction.Jsr ->
        match _ir.TargetOperand with
        | Addr address -> 
            _r.[6] <- _r.[6] - 2us
            _r.[int register] <- _r.[7]
            _r.[7] <- address
        | _ -> ()

    | _ -> ()

Fable versions

I tested this code with the latest major versions of Fable.

The problem occurs with Fable 0.7.5-alpha.7
The problem occurs with Fable 0.6.15
The problem DOES NOT occurs with Fable 0.5.11.

Related information

Microsoft (R) F# Compiler version 14.0.23020.0
Microsoft .NET Framework 4.5 Multi-Targeting Pack
Microsoft .NET Framework 4.5 SDK
Microsoft Windows [Version 10.0.14393]

bug

All 6 comments

Argh, this must be due to some of the optimizations I tried to implement 馃槙 I tried to removed this but still not working.

Thanks a lot for the code to reproduce the issue, I'm investigating it.

This should be fixed in 0.7.5-alpha.11 (I'll upload it shortly) but I'm not sure how to test it beyond checking the code compiles. Could you please write a test case? Cheers!

Great! At first glance I can attest 0.7.5-alpha.11 fixed the problem. I will test it more thoroughly and come back to confirm.

Could you please write a test case?

Sure! Consider it done! 馃槈 -- While I don't know yet the exact cause of the problem (my minimal test sample above was made by trial and error) I will check your fixes and make a test to guard against it :) 馃憤

BTW: It is worthy to backport this fix to 0.6.x series? (while 0.7.x is in alpha...)

Great, nice to hear it's working! The problem was that switch cases weren't creating a new scope, and declaring matchValue in both cases made Babel complain (case 1: let matchValue = ... case 2: let matchValue = ... . Now I create a block scope for each case: case 1: { let matchValue = ... } case 2: { let matchValue = ... } and it seems to work 馃槃

About the test case, I already put your code in a test but as it's quite complex I'm not sure what to feed Execute. If you can just provide a cpu instantiation and the expected result that'll make the test more complete :+1:

Do you need this in 0.6.x soon? Can't you use alpha for the moment? I'll be releasing _stablish_ 0.7 by the end of the week or beginning of the next, so it'll be much more easier to do the full merge then instead of cherry-picking fixes.

No worries. I can use alpha. 馃槃 . It's just that occurred to me that the problem exists in the latest "stable" version. But, no problem. Let's keep it simple. (or until another user found it 馃槄 )

BTW: I did see the test case. I will polish it (and, I hope, try to make it simpler).

Finally: I'm also started to get an "Invalid method name type MemberExpression" warning during the compilation using 0.7.x. (it is not an error because the compilation suceeds -- but this message is written several times do the console). I will try to isolate it to know if is related with this issue or not.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alfonsogarciacaro picture alfonsogarciacaro  路  28Comments

matthid picture matthid  路  29Comments

sergey-tihon picture sergey-tihon  路  70Comments

ed-ilyin picture ed-ilyin  路  48Comments

dbrattli picture dbrattli  路  54Comments