Skip to content

Go 1.10 support. #725

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

Closed
dmitshur opened this issue Dec 8, 2017 · 22 comments · Fixed by #755
Closed

Go 1.10 support. #725

dmitshur opened this issue Dec 8, 2017 · 22 comments · Fixed by #755

Comments

@dmitshur
Copy link
Member

dmitshur commented Dec 8, 2017

This is an issue to track work to support Go 1.10. go1.10beta1 has been released today.

I plan to explore this in the next few coming days.

@dmitshur
Copy link
Member Author

dmitshur commented Dec 12, 2017

I've started looking into this on go1.10 branch.

The current status is that runtime package doesn't compile because of missing identifiers:

runtime/error.go:134:8: undeclared name: getcallerpc
runtime/error.go:135:10: undeclared name: funcname
runtime/error.go:135:19: undeclared name: findfunc

Edit: This has been resolved in 2fd19ac.

@dmitshur
Copy link
Member Author

dmitshur commented Dec 13, 2017

Made good progress so far. Go 1.10 seems to have relatively few breaking internal changes to update for (so far).

As of commit e092078, on macOS where I'm doing development, gopherjs test is passing for all packages except these:

html/template
io
path/filepath
reflect
strings

The Go reposiory compiler tests (TestGoRepositoryCompilerTests) are mostly passing, the current state is:

  315 ok  
   34 knfl
    3 FAIL
    1 unok

On Linux, it's running into some issue causing it block and never complete, so nothing works in CircleCI right now.

I'll make things work on macOS first, then switch to Linux to fix the rest of the issues.

@ghost
Copy link

ghost commented Dec 13, 2017

@shurcooL thanks for doing this.

Not sure if your aware of this ?

go version go1.10beta1 darwin/amd64

go get -u github.com/gopherjs/gopherjs
# github.com/gopherjs/gopherjs/compiler
../../../../../../../gopherjs/gopherjs/compiler/compiler.go:20:9: undefined: ___GOPHERJS_REQUIRES_GO_VERSION_1_9___

@myitcv
Copy link
Member

myitcv commented Dec 13, 2017

@gedw99 the Go 1.10 support is being developed on a branch. A plain go get -u will try to update from master. You'll need to do something like:

cd `go list -f '{{.Dir}}' github.com/gopherjs/gopherjs`
git fetch
git checkout -f origin/go1.10
go install

Hope that helps.

@ghost
Copy link

ghost commented Dec 13, 2017

@myitcv cheers. will give it a go.

@dmitshur
Copy link
Member Author

Got all reflect tests to pass. There were some complications and remaining TODOs. I'm not completely confident in some of the fixes, they'll need to be reviewed and evaluated more closely in the end (but I am confident in the rest).

$ gopherjs test reflect
PASS
ok  	reflect	82.138s

@ghost
Copy link

ghost commented Dec 14, 2017

make an announced asking for users to test on reddit or wherever ?

@dmitshur
Copy link
Member Author

It's not ready for testing yet. When it is, I will announce that.

@ghost
Copy link

ghost commented Dec 15, 2017 via email

@dmitshur
Copy link
Member Author

Addressed some of the remaining TODOs (but not all) in the reflect package changes, and cleaned up the commit messages. They're now pushed.

Moving onto the remaining packages with failing tests on macOS.

@dmitshur
Copy link
Member Author

Package strings tests are passing as of 2272dd2. What's left now is:

$ gopherjs test io
--- FAIL: TestMultiWriterSingleChainFlatten (0.00s)
	multi_test.go:174: multiWriter did not flatten chained multiWriters: expected writeDepth 12, got 4
FAIL
FAIL	io	0.697s

$ gopherjs test html/template
--- FAIL: TestEscapingNilNonemptyInterfaces (0.01s)

/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.749514704:9591
			if (!(($parseInt(methodSet.length) === 0)) || !!(typ.named)) {
                              ^
TypeError: Cannot read property 'length' of undefined
    at reflectType (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.749514704:9591:31)
    at Object.TypeOf (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/reflect.go:306:3)
    at indirect (/html/template/content.go:110:6)
    at stringify (/html/template/content.go:144:4)
    at htmlEscaper (/html/template/html.go:43:3)
    at $call (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.749514704:30:50)
    at /Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.749514704:1942:22
    at Object.$packages.reflect.Value.ptr.call (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/reflect.go:874:3)
    at Object.$packages.reflect.Value.ptr.Call (/reflect/value.go:308:3)
    at Object.$packages.text/template.state.ptr.evalCall (/text/template/exec.go:703:3)
    at Object.$packages.text/template.state.ptr.evalFunction (/text/template/exec.go:571:3)
    at Object.$packages.text/template.state.ptr.evalCommand (/text/template/exec.go:468:4)
    at Object.$packages.text/template.state.ptr.evalPipeline (/text/template/exec.go:441:4)
    at Object.$packages.text/template.state.ptr.walk (/text/template/exec.go:240:4)
    at Object.$packages.text/template.state.ptr.walk (/text/template/exec.go:248:8)
    at Object.$packages.text/template.Template.ptr.execute (/text/template/exec.go:195:3)
    at Object.$packages.text/template.Template.ptr.Execute (/text/template/exec.go:178:3)
    at Object.$packages.html/template.Template.ptr.Execute (/html/template/template.go:122:3)
    at Object.TestEscapingNilNonemptyInterfaces [as $blk] (/html/template/content_test.go:310:3)
    at Object.tRunner [as $blk] (/testing/testing.go:774:3)
    at fun (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.749514704:1473:37)
    at $goroutine (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.749514704:1471:19)
    at $runScheduled (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.749514704:1511:7)
    at $schedule (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.749514704:1527:5)
    at $go (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.749514704:1503:3)
    at Object.<anonymous> (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.749514704:54541:1)
    at Object.<anonymous> (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.749514704:54544:4)
    at Module._compile (module.js:641:30)
    at Object.Module._extensions..js (module.js:652:10)
    at Module.load (module.js:560:32)
    at tryModuleLoad (module.js:503:12)
    at Function.Module._load (module.js:495:3)
    at Function.Module.runMain (module.js:682:10)
    at startup (bootstrap_node.js:191:16)
    at bootstrap_node.js:613:3
FAIL	html/template	0.973s

$ gopherjs test path/filepath
--- FAIL: TestWalk (0.01s)
	path_test.go:367: makeTree: open testdata/a: no such file or directory
	path_test.go:367: makeTree: open testdata/c: no such file or directory
	path_test.go:367: makeTree: open testdata/d/x: no such file or directory
	path_test.go:367: makeTree: open testdata/d/z/u: no such file or directory
	path_test.go:367: makeTree: open testdata/d/z/v: no such file or directory

/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.897754214:1412
          throw new Error(msg);
                ^
Error: runtime error: invalid memory address or nil pointer dereference
    at $callDeferred (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.897754214:1412:17)
    at $panic (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.897754214:1451:3)
    at $b (/testing/testing.go:739:5)
    at $callDeferred (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.897754214:1424:23)
    at $panic (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.897754214:1451:3)
    at throw$1 (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/runtime.go:219:3)
    at Object.$throwNilPointerError (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.897754214:29:42)
    at mark (/path/filepath/path_test.go:392:3)
    at $b (/path/filepath/path_test.go:440:4)
    at Object.Walk (/path/filepath/path.go:401:4)
    at TestWalk (/path/filepath/path_test.go:443:3)
    at tRunner (/testing/testing.go:774:3)
    at $goroutine (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.897754214:1471:19)
    at $runScheduled (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.897754214:1511:7)
    at $schedule (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.897754214:1527:5)
    at $go (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.897754214:1503:3)
    at Object.<anonymous> (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.897754214:38272:1)
    at Object.<anonymous> (/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/gopherjs/gopherjs/test.897754214:38275:4)
    at Module._compile (module.js:641:30)
    at Object.Module._extensions..js (module.js:652:10)
    at Module.load (module.js:560:32)
    at tryModuleLoad (module.js:503:12)
    at Function.Module._load (module.js:495:3)
    at Function.Module.runMain (module.js:682:10)
    at startup (bootstrap_node.js:191:16)
    at bootstrap_node.js:613:3
FAIL	path/filepath	0.630s

@myitcv myitcv mentioned this issue Jan 2, 2018
@dmitshur
Copy link
Member Author

A few small updates on my progress here.

Most notably, I've figured out the Linux issue causing stalls, making CI output completely useless. It was an incorrect implementation of syscall.Exit for Linux operating system. It has been fixed in 6a853f3, and CI output is now useful.

Also, I've found that commit 2f2d5b3 was incorrect/incomplete and reverted it in da23df8. I decided to go in the opposite direction and found a valid fix that didn't break other things in 0cb05c5.

With all that, CI is pretty close to passing. Next up I'll triage the 5 new fails in TestGoRepositoryCompilerTests (they're all new to Go 1.10 so likely failing due to relying on features GopherJS doesn't support).

@dmitshur
Copy link
Member Author

dmitshur commented Feb 9, 2018

Next up I'll triage the 5 new fails in TestGoRepositoryCompilerTests (they're all new to Go 1.10 so likely failing due to relying on features GopherJS doesn't support).

That has been done in commit 0964c58.

Now, what's left are following 4 failures in CI (i.e., on Linux):

=== RUN   TestTypeRace
--- FAIL: TestTypeRace (0.00s)
/home/ubuntu/gopherjs/test.910613175:4
Error.stackTraceLimit=Infinity;var $global,$module;if(typeof window!=="undefined"){$global=window;}else if(typeof self!=="undefined"){$global=self;}else if(typeof global!=="undefined"){$global=global;$global.require=require;}else{$global=this;}if($global===undefined||$global.Array===undefined){throw new Error("no global object found");}if(typeof module!=="undefined"){$module=module;}var $packages={},$idCounter=0;var $keys=function(m){return m?Object.keys(m):[];};var $flushConsole=function(){};var $throwRuntimeError;var $throwNilPointerError=function(){$throwRuntimeError("invalid memory address or nil pointer dereference");};var $call=function(fn,rcvr,args){return fn.apply(rcvr,args);};var $makeFunc=function(fn){return function(){return $externalize(fn(this,new($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments,[]))),$emptyInterface);};};var $unused=function(v){};var $mapArray=function(array,f){var newArray=new array.constructor(array.length);for(var

Error: sync: WaitGroup counter not zero
    at $callDeferred (/home/ubuntu/gopherjs/test.910613175:4:29086)
    at $panic (/home/ubuntu/gopherjs/test.910613175:4:29710)
    at $b (/home/ubuntu/gopherjs/test.910613175:43:74961)
    at $callDeferred (/home/ubuntu/gopherjs/test.910613175:4:29257)
    at $panic (/home/ubuntu/gopherjs/test.910613175:4:29710)
    at $packages.github.com/gopherjs/gopherjs/nosync.D.ptr.Wait (/home/ubuntu/gopherjs/test.910613175:23:5363)
    at $packages.encoding/gob.QQ (/home/ubuntu/gopherjs/test.910613175:44:554653)
    at $packages.testing.CS (/home/ubuntu/gopherjs/test.910613175:43:76555)
    at $goroutine (/home/ubuntu/gopherjs/test.910613175:4:30280)
    at $runScheduled (/home/ubuntu/gopherjs/test.910613175:4:30991)
    at $schedule (/home/ubuntu/gopherjs/test.910613175:4:31219)
    at $go (/home/ubuntu/gopherjs/test.910613175:4:30868)
    at Object.<anonymous> (/home/ubuntu/gopherjs/test.910613175:55:1)
    at Object.<anonymous> (/home/ubuntu/gopherjs/test.910613175:58:4)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.runMain (module.js:575:10)
    at run (node.js:348:7)
    at startup (node.js:140:9)
    at node.js:463:3
FAIL	encoding/gob	3.030s

=== RUN   TestEscapingNilNonemptyInterfaces
--- FAIL: TestEscapingNilNonemptyInterfaces (0.01s)
/home/ubuntu/gopherjs/test.675118677:4
Error.stackTraceLimit=Infinity;var $global,$module;if(typeof window!=="undefined"){$global=window;}else if(typeof self!=="undefined"){$global=self;}else if(typeof global!=="undefined"){$global=global;$global.require=require;}else{$global=this;}if($global===undefined||$global.Array===undefined){throw new Error("no global object found");}if(typeof module!=="undefined"){$module=module;}var $packages={},$idCounter=0;var $keys=function(m){return m?Object.keys(m):[];};var $flushConsole=function(){};var $throwRuntimeError;var $throwNilPointerError=function(){$throwRuntimeError("invalid memory address or nil pointer dereference");};var $call=function(fn,rcvr,args){return fn.apply(rcvr,args);};var $makeFunc=function(fn){return function(){return $externalize(fn(this,new($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments,[]))),$emptyInterface);};};var $unused=function(v){};var $mapArray=function(array,f){var newArray=new array.constructor(array.length);for(var

TypeError: Cannot read property 'length' of undefined
    at $packages.reflect.L (/home/ubuntu/gopherjs/test.675118677:19:12759)
    at Object.$packages.reflect.AD [as TypeOf] (/home/ubuntu/gopherjs/test.675118677:19:20865)
    at $packages.html/template.AD (/home/ubuntu/gopherjs/test.675118677:43:13569)
    at $packages.html/template.AH (/home/ubuntu/gopherjs/test.675118677:43:15982)
    at $packages.html/template.CO (/home/ubuntu/gopherjs/test.675118677:43:74541)
    at $call (/home/ubuntu/gopherjs/test.675118677:4:676)
    at /home/ubuntu/gopherjs/test.675118677:4:39121
    at $packages.reflect.FB.ptr.call (/home/ubuntu/gopherjs/test.675118677:19:42989)
    at $packages.reflect.FB.ptr.Call (/home/ubuntu/gopherjs/test.675118677:19:100528)
    at $packages.text/template.P.ptr.evalCall (/home/ubuntu/gopherjs/test.675118677:42:46841)
    at $packages.text/template.P.ptr.evalFunction (/home/ubuntu/gopherjs/test.675118677:42:36084)
    at $packages.text/template.P.ptr.evalCommand (/home/ubuntu/gopherjs/test.675118677:42:27365)
    at $packages.text/template.P.ptr.evalPipeline (/home/ubuntu/gopherjs/test.675118677:42:24200)
    at $packages.text/template.P.ptr.walk (/home/ubuntu/gopherjs/test.675118677:42:13227)
    at $packages.text/template.P.ptr.walk (/home/ubuntu/gopherjs/test.675118677:42:13940)
    at $packages.text/template.CO.ptr.execute (/home/ubuntu/gopherjs/test.675118677:42:10860)
    at $packages.text/template.CO.ptr.Execute (/home/ubuntu/gopherjs/test.675118677:42:9490)
    at $packages.html/template.DK.ptr.Execute (/home/ubuntu/gopherjs/test.675118677:43:92142)
    at Object.$packages.html/template.FZ [as $blk] (/home/ubuntu/gopherjs/test.675118677:43:172417)
    at Object.$packages.testing.CS [as $blk] (/home/ubuntu/gopherjs/test.675118677:39:74800)
    at fun (/home/ubuntu/gopherjs/test.675118677:4:30352)
    at $goroutine (/home/ubuntu/gopherjs/test.675118677:4:30280)
    at $runScheduled (/home/ubuntu/gopherjs/test.675118677:4:30991)
    at $schedule (/home/ubuntu/gopherjs/test.675118677:4:31219)
    at $go (/home/ubuntu/gopherjs/test.675118677:4:30868)
    at Object.<anonymous> (/home/ubuntu/gopherjs/test.675118677:55:1)
    at Object.<anonymous> (/home/ubuntu/gopherjs/test.675118677:58:4)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.runMain (module.js:575:10)
    at run (node.js:348:7)
    at startup (node.js:140:9)
    at node.js:463:3
FAIL	html/template	1.269s

=== RUN   TestMultiWriterSingleChainFlatten
--- FAIL: TestMultiWriterSingleChainFlatten (0.01s)
	test.558082205:38: multiWriter did not flatten chained multiWriters: expected writeDepth 12, got 4
FAIL	io	0.888s

=== RUN   TestBuilder
--- FAIL: TestBuilder (0.01s)
/home/ubuntu/gopherjs/test.555614069:4
Error.stackTraceLimit=Infinity;var $global,$module;if(typeof window!=="undefined"){$global=window;}else if(typeof self!=="undefined"){$global=self;}else if(typeof global!=="undefined"){$global=global;$global.require=require;}else{$global=this;}if($global===undefined||$global.Array===undefined){throw new Error("no global object found");}if(typeof module!=="undefined"){$module=module;}var $packages={},$idCounter=0;var $keys=function(m){return m?Object.keys(m):[];};var $flushConsole=function(){};var $throwRuntimeError;var $throwNilPointerError=function(){$throwRuntimeError("invalid memory address or nil pointer dereference");};var $call=function(fn,rcvr,args){return fn.apply(rcvr,args);};var $makeFunc=function(fn){return function(){return $externalize(fn(this,new($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments,[]))),$emptyInterface);};};var $unused=function(v){};var $mapArray=function(array,f){var newArray=new array.constructor(array.length);for(var

TypeError: Cannot create property '$proxies' on number '0'
    at $pointerOfStructConversion (/home/ubuntu/gopherjs/test.555614069:4:5633)
    at $packages.strings.J.ptr.copyCheck (/home/ubuntu/gopherjs/test.555614069:27:4509)
    at $packages.strings.J.ptr.WriteString (/home/ubuntu/gopherjs/test.555614069:27:6184)
    at $packages.strings_test.N (/home/ubuntu/gopherjs/test.555614069:35:11457)
    at $packages.testing.CS (/home/ubuntu/gopherjs/test.555614069:34:76607)
    at $goroutine (/home/ubuntu/gopherjs/test.555614069:4:30280)
    at $runScheduled (/home/ubuntu/gopherjs/test.555614069:4:30991)
    at $schedule (/home/ubuntu/gopherjs/test.555614069:4:31219)
    at $go (/home/ubuntu/gopherjs/test.555614069:4:30868)
    at Object.<anonymous> (/home/ubuntu/gopherjs/test.555614069:45:1)
    at Object.<anonymous> (/home/ubuntu/gopherjs/test.555614069:48:4)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.runMain (module.js:575:10)
    at run (node.js:348:7)
    at startup (node.js:140:9)
    at node.js:463:3
FAIL	strings	5.481s

(They also reproduce on macOS.)

@dmitshur
Copy link
Member Author

dmitshur commented Feb 16, 2018

I've figured out the strings TestBuilder failure. It's because of some unsafe.Pointer manipulation added in rc2 (see golang/go@484586c). Just need to remove it. Edit: Done in commit e91feea.

Three more to go.

@dmitshur
Copy link
Member Author

Fixing io turned out easy, TestMultiWriterSingleChainFlatten just needed to be skipped because it uses unsupported runtime features.

Done in commit e11ce77.

@dmitshur
Copy link
Member Author

dmitshur commented Feb 16, 2018

Working on the encoding/gob failure now. I've figured out why it's happening, just need to decide on a resolution now. Edit: Done in commit aff7ec6 and filed #754 for further consideration.

Only 1 more thing left to investigate go now:

=== RUN   TestEscapingNilNonemptyInterfaces
--- FAIL: TestEscapingNilNonemptyInterfaces (0.01s)
/home/ubuntu/gopherjs/test.675118677:4
Error.stackTraceLimit=Infinity;var $global,$module;if(typeof window!=="undefined"){$global=window;}else if(typeof self!=="undefined"){$global=self;}else if(typeof global!=="undefined"){$global=global;$global.require=require;}else{$global=this;}if($global===undefined||$global.Array===undefined){throw new Error("no global object found");}if(typeof module!=="undefined"){$module=module;}var $packages={},$idCounter=0;var $keys=function(m){return m?Object.keys(m):[];};var $flushConsole=function(){};var $throwRuntimeError;var $throwNilPointerError=function(){$throwRuntimeError("invalid memory address or nil pointer dereference");};var $call=function(fn,rcvr,args){return fn.apply(rcvr,args);};var $makeFunc=function(fn){return function(){return $externalize(fn(this,new($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments,[]))),$emptyInterface);};};var $unused=function(v){};var $mapArray=function(array,f){var newArray=new array.constructor(array.length);for(var

TypeError: Cannot read property 'length' of undefined
    at $packages.reflect.L (/home/ubuntu/gopherjs/test.675118677:19:12759)
    at Object.$packages.reflect.AD [as TypeOf] (/home/ubuntu/gopherjs/test.675118677:19:20865)
    at $packages.html/template.AD (/home/ubuntu/gopherjs/test.675118677:43:13569)
    at $packages.html/template.AH (/home/ubuntu/gopherjs/test.675118677:43:15982)
    at $packages.html/template.CO (/home/ubuntu/gopherjs/test.675118677:43:74541)
    at $call (/home/ubuntu/gopherjs/test.675118677:4:676)
    at /home/ubuntu/gopherjs/test.675118677:4:39121
    at $packages.reflect.FB.ptr.call (/home/ubuntu/gopherjs/test.675118677:19:42989)
    at $packages.reflect.FB.ptr.Call (/home/ubuntu/gopherjs/test.675118677:19:100528)
    at $packages.text/template.P.ptr.evalCall (/home/ubuntu/gopherjs/test.675118677:42:46841)
    at $packages.text/template.P.ptr.evalFunction (/home/ubuntu/gopherjs/test.675118677:42:36084)
    at $packages.text/template.P.ptr.evalCommand (/home/ubuntu/gopherjs/test.675118677:42:27365)
    at $packages.text/template.P.ptr.evalPipeline (/home/ubuntu/gopherjs/test.675118677:42:24200)
    at $packages.text/template.P.ptr.walk (/home/ubuntu/gopherjs/test.675118677:42:13227)
    at $packages.text/template.P.ptr.walk (/home/ubuntu/gopherjs/test.675118677:42:13940)
    at $packages.text/template.CO.ptr.execute (/home/ubuntu/gopherjs/test.675118677:42:10860)
    at $packages.text/template.CO.ptr.Execute (/home/ubuntu/gopherjs/test.675118677:42:9490)
    at $packages.html/template.DK.ptr.Execute (/home/ubuntu/gopherjs/test.675118677:43:92142)
    at Object.$packages.html/template.FZ [as $blk] (/home/ubuntu/gopherjs/test.675118677:43:172417)
    at Object.$packages.testing.CS [as $blk] (/home/ubuntu/gopherjs/test.675118677:39:74800)
    at fun (/home/ubuntu/gopherjs/test.675118677:4:30352)
    at $goroutine (/home/ubuntu/gopherjs/test.675118677:4:30280)
    at $runScheduled (/home/ubuntu/gopherjs/test.675118677:4:30991)
    at $schedule (/home/ubuntu/gopherjs/test.675118677:4:31219)
    at $go (/home/ubuntu/gopherjs/test.675118677:4:30868)
    at Object.<anonymous> (/home/ubuntu/gopherjs/test.675118677:55:1)
    at Object.<anonymous> (/home/ubuntu/gopherjs/test.675118677:58:4)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.runMain (module.js:575:10)
    at run (node.js:348:7)
    at startup (node.js:140:9)
    at node.js:463:3
FAIL	html/template	1.269s

@dmitshur
Copy link
Member Author

dmitshur commented Feb 16, 2018

I'm actively investigating the html/template failure now. I think I've finally cracked it.

This wasn't trivial to track down. I started with the following simplified test case from html/template that was resulting in a runtime TypeError:

package main

import (
	"bytes"
	"html/template"
)

func main() {
	tmpl := template.Must(template.New("x").Parse("{{.E}}"))
	got := new(bytes.Buffer)
	testData := struct{ E error }{} // any non-empty interface here will do; error is just ready at hand
	tmpl.Execute(got, testData)
}
go/src/github.com/shurcooL/play/241/main.go.054367643:8576
			if (!(($parseInt(methodSet.length) === 0)) || !!(typ.named)) {
                              ^
TypeError: Cannot read property 'length' of undefined
    at reflectType (go/src/github.com/shurcooL/play/241/main.go.054367643:8576:31)
    at Object.TypeOf (go/src/github.com/shurcooL/play/241/reflect.go:312:3)
    at indirect (/github.com/shurcooL/play/241/main.go:301:6)
    at stringify (/github.com/shurcooL/play/241/main.go:337:4)
    at htmlEscaper (/github.com/shurcooL/play/241/main.go:2077:3)
    at $call (go/src/github.com/shurcooL/play/241/main.go.054367643:30:50)
    at go/src/github.com/shurcooL/play/241/main.go.054367643:1948:22
    at Object.$packages.reflect.Value.ptr.call (go/src/github.com/shurcooL/play/241/reflect.go:880:3)
    at Object.$packages.reflect.Value.ptr.Call (/reflect/value.go:308:3)
    at Object.$packages.text/template.state.ptr.evalCall (/text/template/exec.go:667:3)
    at Object.$packages.text/template.state.ptr.evalFunction (/text/template/exec.go:535:3)
    at Object.$packages.text/template.state.ptr.evalCommand (/text/template/exec.go:432:4)
    at Object.$packages.text/template.state.ptr.evalPipeline (/text/template/exec.go:405:4)
    at Object.$packages.text/template.state.ptr.walk (/text/template/exec.go:231:4)
    at Object.$packages.text/template.state.ptr.walk (/text/template/exec.go:239:5)
    at Object.$packages.text/template.Template.ptr.execute (/text/template/exec.go:194:3)
    at Object.$packages.text/template.Template.ptr.Execute (/text/template/exec.go:177:3)
    at Object.$packages.main.Template.ptr.Execute (/github.com/shurcooL/play/241/main.go:2791:3)
    at Object.main (/github.com/shurcooL/play/241/main.go:24:3)
    at Object.$init [as $blk] (go/src/github.com/shurcooL/play/241/main.go.054367643:39333:70)
    at fun (go/src/github.com/shurcooL/play/241/main.go.054367643:1479:37)
    at $goroutine (go/src/github.com/shurcooL/play/241/main.go.054367643:1477:19)
    at $runScheduled (go/src/github.com/shurcooL/play/241/main.go.054367643:1517:7)
    at $schedule (go/src/github.com/shurcooL/play/241/main.go.054367643:1533:5)
    at $go (go/src/github.com/shurcooL/play/241/main.go.054367643:1509:3)
    at Object.<anonymous> (go/src/github.com/shurcooL/play/241/main.go.054367643:39344:1)
    at Object.<anonymous> (go/src/github.com/shurcooL/play/241/main.go.054367643:39347:4)
    at Module._compile (module.js:660:30)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
    at Function.Module.runMain (module.js:701:10)
    at startup (bootstrap_node.js:190:16)
    at bootstrap_node.js:662:3

This was a bad failure because it's not a new test, but rather a regression. It worked fine in GopherJS 1.9-*, see https://gopherjs.github.io/playground/#/IE9P-DGnM8 (at this time, GopherJS Playground is still on 1.9).

I modified GopherJS reflect code to print the value of methodSet before that TypeError, and it was being undefined. $methodSet was returning undefined rather than an array of methods. Adding a methodSet != js.Undefined guard before methodSet.Length() != 0 in reflectType allowed the TypeOf code to proceed and give me more context about the failure.

I made a local copy of html/template that I could modify, and I was able to discover the problem was in the following code of html/template helper:

// indirectToStringerOrError returns the value, after dereferencing as many times
// as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
// or error,
func indirectToStringerOrError(a interface{}) interface{} {
	if a == nil {
		println("indirectToStringerOrError: was nil")
		return nil
	}
	panic("indirectToStringerOrError: wasn't nil!")
	v := reflect.ValueOf(a)
	for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
		v = v.Elem()
	}
	return v.Interface()
}

What should've been happening (for the sample input of the test program) is a == nil should've been true. Instead, after I avoided the TypeError by adding a methodSet != js.Undefined guard, what happened was a == nil was being reported as false.

The problem was related to commit 1fb1aaa, which tried to fix a failing test, but (as the commit message hinted), it was not a complete fix. Instead of fixing the real problem, it was simply masking one of its symptoms, allowing TestCallConvert to incorrectly pass, but html/template's test and underlying behavior was still broken.

Then I started looking at the issue golang/go#22143, and commit golang/go@eafa29b that resolved it for gc and gccgo compilers. What was interesting is that the issue golang/go#22143 was only affecting gc and gccgo, but GopherJS 1.9-* was actually not affected by it—it was working correctly to begin with. The change in commit golang/go@eafa29b was the one that was causing these issues for GopherJS. Simply undoing it (for GopherJS only) resolves all problems, allowing all reflect and html/template tests to continue to pass in GopherJS under Go 1.10. Phew!

Edit: Fix pushed in 28e102c. 🤞

@theclapp
Copy link

I continue to be impressed by the thoroughness of your GitHub-fu.

@dmitshur
Copy link
Member Author

dmitshur commented Feb 17, 2018

CI is now green! ✅ 🎉

I've created PR #755 that will resolve this issue. I invite everyone to test and/or review it. Thanks!

@jvsteiner
Copy link

I'm getting the following since upgrading to go 1.10:

gopherjs build -m ../scripts/evat_crypto.go -o ./static/lib/evat_crypto.js
cannot find package "bytes" in any of:
	/Users/jamie/Code/go/src/github.com/Guardtime/evat/vendor/bytes (vendor tree)
	/usr/local/Cellar/go/1.9.4/libexec/src/bytes (from $GOROOT)
	/Users/jamie/Code/go/src/bytes (from $GOPATH)

any chance it's related?

@dmitshur
Copy link
Member Author

@jvsteiner Did you rebuild gopherjs from the go1.10 branch after upgrading to Go 1.10?

@jvsteiner
Copy link

my mistake, working now. sorry for spam. for others who failed to RTFM upthread:

  1. checkout the right branch
  2. go install

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants