@@ -1991,24 +1991,23 @@ func compileComprehensionExpr(ctx *blockCtx, lhs int, v *ast.ComprehensionExpr)
19911991 )
19921992 kind := comprehensionKind (v )
19931993 pkg , cb := ctx .pkg , ctx .cb
1994+ pkgTypes := pkg .Types
19941995 var results * types.Tuple
19951996 var ret * types.Var
19961997 if v .Elt == nil {
1997- boolean := pkg .NewParam (token .NoPos , nameOk , types .Typ [types .Bool ])
1998+ boolean := types .NewParam (token .NoPos , pkgTypes , nameOk , types .Typ [types .Bool ])
19981999 results = types .NewTuple (boolean )
19992000 } else {
2000- ret = pkg .NewAutoParam (nameRet )
2001+ // use tyInvalid as unbounded return type
2002+ ret = types .NewParam (token .NoPos , pkgTypes , nameRet , types .Typ [types .Invalid ])
20012003 if kind == comprehensionSelect && lhs == 2 {
2002- boolean := pkg .NewParam (token .NoPos , nameOk , types .Typ [types .Bool ])
2004+ boolean := types .NewParam (token .NoPos , pkgTypes , nameOk , types .Typ [types .Bool ])
20032005 results = types .NewTuple (ret , boolean )
20042006 } else {
20052007 results = types .NewTuple (ret )
20062008 }
20072009 }
20082010 cb .NewClosure (nil , results , false ).BodyStart (pkg )
2009- if kind == comprehensionMap {
2010- cb .VarRef (ret ).ZeroLit (ret .Type ()).Assign (1 )
2011- }
20122011 end := 0
20132012 for i := len (v .Fors ) - 1 ; i >= 0 ; i -- {
20142013 names := make ([]string , 0 , 2 )
@@ -2040,21 +2039,30 @@ func compileComprehensionExpr(ctx *blockCtx, lhs int, v *ast.ComprehensionExpr)
20402039 }
20412040 end ++
20422041 }
2042+ stk := cb .InternalStack ()
20432043 switch kind {
20442044 case comprehensionList :
20452045 // _xgo_ret = append(_xgo_ret, elt)
2046+ compileExpr (ctx , 1 , v .Elt )
2047+ e := stk .Pop ()
2048+ * ret = * types .NewVar (token .NoPos , pkgTypes , nameRet , types .NewSlice (e .Type ))
20462049 cb .VarRef (ret )
20472050 cb .Val (pkg .Builtin ().Ref ("append" ))
20482051 cb .Val (ret )
2049- compileExpr ( ctx , 1 , v . Elt )
2052+ stk . Push ( e )
20502053 cb .Call (2 ).Assign (1 )
20512054 case comprehensionMap :
20522055 // _xgo_ret[key] = val
2053- cb .Val (ret )
20542056 kv := v .Elt .(* ast.KeyValueExpr )
20552057 compileExpr (ctx , 1 , kv .Key )
2056- cb . IndexRef ( 1 )
2058+ key := stk . Pop ( )
20572059 compileExpr (ctx , 1 , kv .Value )
2060+ val := stk .Pop ()
2061+ * ret = * types .NewVar (token .NoPos , pkgTypes , nameRet , types .NewMap (key .Type , val .Type ))
2062+ cb .Val (ret )
2063+ stk .Push (key )
2064+ cb .IndexRef (1 )
2065+ stk .Push (val )
20582066 cb .Assign (1 )
20592067 default :
20602068 if v .Elt == nil {
@@ -2064,6 +2072,8 @@ func compileComprehensionExpr(ctx *blockCtx, lhs int, v *ast.ComprehensionExpr)
20642072 } else {
20652073 // return elt, true
20662074 compileExpr (ctx , 1 , v .Elt )
2075+ e := stk .Get (- 1 )
2076+ * ret = * types .NewVar (token .NoPos , pkgTypes , nameRet , e .Type )
20672077 n := 1
20682078 if lhs == 2 {
20692079 cb .Val (true )
@@ -2075,6 +2085,9 @@ func compileComprehensionExpr(ctx *blockCtx, lhs int, v *ast.ComprehensionExpr)
20752085 for i := 0 ; i < end ; i ++ {
20762086 cb .End ()
20772087 }
2088+ if kind == comprehensionMap {
2089+ cb .VarRef (ret ).MapLit (ret .Type (), 0 , v ).Assign (1 ).MoveLastStmtTo (0 )
2090+ }
20782091 cb .Return (0 ).End ().Call (0 )
20792092}
20802093
0 commit comments