Repository: traefik/yaegi (Go)

Issue:
aliased string used as a slice
The following program `sample.go` triggers a panic:

```go
package main

type str string
    
func main() {
    var s str = "truc"
    println(s[1] == 'r')
}
```

Expected result:
```console
$ go run ./sample.go
true
```

Got:
```console
$ yaegi ./sample.go
scope.go:212: nil type
run: /home/marc/sample.go:7:10: CFG post-order panic: nil type
goroutine 1 [running]:
runtime/debug.Stack(0x1, 0xc0002e2600, 0x40)
        /usr/lib/go/src/runtime/debug/stack.go:24 +0x9f
github.com/traefik/yaegi/interp.(*Interpreter).eval.func1(0xc00013dc70)
        /home/marc/go/src/github.com/traefik/yaegi/interp/interp.go:485 +0xc5
panic(0xeaf880, 0xc000204ec0)
        /usr/lib/go/src/runtime/panic.go:969 +0x1b9
github.com/traefik/yaegi/interp.(*Interpreter).cfg.func2.1(0xc000215700)
        /home/marc/go/src/github.com/traefik/yaegi/interp/cfg.go:461 +0xb3
panic(0xdd1b00, 0xc0002066e0)
        /usr/lib/go/src/runtime/panic.go:969 +0x1b9
log.Panic(0xc00013ce98, 0x1, 0x1)
        /usr/lib/go/src/log/log.go:351 +0xae
github.com/traefik/yaegi/interp.(*scope).add(0xc000212400, 0x0, 0x0)
        /home/marc/go/src/github.com/traefik/yaegi/interp/scope.go:212 +0x1c5
github.com/traefik/yaegi/interp.(*Interpreter).cfg.func2(0xc000215700)
        /home/marc/go/src/github.com/traefik/yaegi/interp/cfg.go:761 +0x6fb4
github.com/traefik/yaegi/interp.(*node).Walk(0xc000215700, 0xc00013daf8, 0xc00013dac8)
        /home/marc/go/src/github.com/traefik/yaegi/interp/interp.go:225 +0xa5
github.com/traefik/yaegi/interp.(*node).Walk(0xc000215600, 0xc00013daf8, 0xc00013dac8)
        /home/marc/go/src/github.com/traefik/yaegi/interp/interp.go:222 +0x66
github.com/traefik/yaegi/interp.(*node).Walk(0xc000215400, 0xc00013daf8, 0xc00013dac8)
        /home/marc/go/src/github.com/traefik/yaegi/interp/interp.go:222 +0x66
github.com/traefik/yaegi/interp.(*node).Walk(0xc000215300, 0xc00013daf8, 0xc00013dac8)
        /home/marc/go/src/github.com/traefik/yaegi/interp/interp.go:222 +0x66
github.com/traefik/yaegi/interp.(*node).Walk(0xc000214c00, 0xc00013daf8, 0xc00013dac8)
        /home/marc/go/src/github.com/traefik/yaegi/interp/interp.go:222 +0x66
github.com/traefik/yaegi/interp.(*node).Walk(0xc000214700, 0xc00013daf8, 0xc00013dac8)
        /home/marc/go/src/github.com/traefik/yaegi/interp/interp.go:222 +0x66
github.com/traefik/yaegi/interp.(*node).Walk(0xc000214100, 0xc00013daf8, 0xc00013dac8)
        /home/marc/go/src/github.com/traefik/yaegi/interp/interp.go:222 +0x66
github.com/traefik/yaegi/interp.(*Interpreter).cfg(0xc000360000, 0xc000214100, 0xc000211938, 0x4, 0xc000211938, 0x4, 0x0, 0x0, 0xc000214100)
        /home/marc/go/src/github.com/traefik/yaegi/interp/cfg.go:63 +0x20f
github.com/traefik/yaegi/interp.(*Interpreter).eval(0xc000360000, 0xc0002bb560, 0x59, 0x7fff364df9dc, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/marc/go/src/github.com/traefik/yaegi/interp/interp.go:512 +0x2f3
github.com/traefik/yaegi/interp.(*Interpreter).EvalPath(0xc000360000, 0x7fff364df9dc, 0x14, 0xc0002bb500, 0x59, 0x0, 0x0, 0xc000217040)
        /home/marc/go/src/github.com/traefik/yaegi/interp/interp.go:399 +0xfa
main.runFile(0xc000360000, 0x7fff364df9dc, 0x14, 0xc000200240, 0x1)
        /home/marc/go/src/github.com/traefik/yaegi/cmd/yaegi/run.go:123 +0xae
main.run(0xc00000e090, 0x1, 0x1, 0x13, 0x13)
        /home/marc/go/src/github.com/traefik/yaegi/cmd/yaegi/run.go:89 +0x7e5
main.main()
        /home/marc/go/src/github.com/traefik/yaegi/cmd/yaegi/yaegi.go:144 +0x415
```



Discussion:

Patch:
diff --git a/interp/cfg.go b/interp/cfg.go
index cb7da805c..050432cf8 100644
--- a/interp/cfg.go
+++ b/interp/cfg.go
@@ -740,7 +740,13 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) {
 			wireChild(n)
 			t := n.child[0].typ
 			switch t.cat {
-			case aliasT, ptrT:
+			case aliasT:
+				if isString(t.val.TypeOf()) {
+					n.typ = sc.getType("byte")
+					break
+				}
+				fallthrough
+			case ptrT:
 				n.typ = t.val
 				if t.val.cat == valueT {
 					n.typ = &itype{cat: valueT, rtype: t.val.rtype.Elem()}


Test patch:
diff --git a/interp/interp_eval_test.go b/interp/interp_eval_test.go
index 61674721d..f604d4886 100644
--- a/interp/interp_eval_test.go
+++ b/interp/interp_eval_test.go
@@ -457,6 +457,7 @@ func TestEvalSliceExpression(t *testing.T) {
 		{src: `a := []int{0,1,2,3}[1::4]`, err: "1:49: 2nd index required in 3-index slice"},
 		{src: `a := []int{0,1,2,3}[1:3:]`, err: "1:51: 3rd index required in 3-index slice"},
 		{src: `a := []int{0,1,2}[3:1]`, err: "invalid index values, must be low <= high <= max"},
+		{pre: func() { eval(t, i, `type Str = string; var r Str = "truc"`) }, src: `r[1]`, res: "114"},
 	})
 }