@@ -157,7 +157,7 @@ func transformCall(n *ir.CallExpr) {
157
157
n .SetOp (ir .OCALLFUNC )
158
158
}
159
159
160
- typecheckaste (ir .OCALL , n .X , n .IsDDD , t .Params (), n .Args , false )
160
+ typecheckaste (ir .OCALL , n .X , n .IsDDD , t .Params (), n .Args )
161
161
if l .Op () == ir .ODOTMETH && len (deref (n .X .Type ().Recv ().Type ).RParams ()) == 0 {
162
162
typecheck .FixMethodCall (n )
163
163
}
@@ -365,59 +365,6 @@ assignOK:
365
365
}
366
366
}
367
367
368
- // Version of transformAssign that can run on generic code that adds CONVIFACE calls
369
- // as needed (and rewrites multi-value calls).
370
- func earlyTransformAssign (stmt ir.Node , lhs , rhs []ir.Node ) {
371
- cr := len (rhs )
372
- if len (rhs ) == 1 {
373
- if rtyp := rhs [0 ].Type (); rtyp != nil && rtyp .IsFuncArgStruct () {
374
- cr = rtyp .NumFields ()
375
- }
376
- }
377
-
378
- // x,y,z = f()
379
- _ , isCallExpr := rhs [0 ].(* ir.CallExpr )
380
- if isCallExpr && cr > len (rhs ) {
381
- stmt := stmt .(* ir.AssignListStmt )
382
- stmt .SetOp (ir .OAS2FUNC )
383
- r := rhs [0 ].(* ir.CallExpr )
384
- rtyp := r .Type ()
385
-
386
- mismatched := false
387
- failed := false
388
- for i := range lhs {
389
- result := rtyp .Field (i ).Type
390
-
391
- if lhs [i ].Type () == nil || result == nil {
392
- failed = true
393
- } else if lhs [i ] != ir .BlankNode && ! types .Identical (lhs [i ].Type (), result ) {
394
- mismatched = true
395
- }
396
- }
397
- if mismatched && ! failed {
398
- typecheck .RewriteMultiValueCall (stmt , r )
399
- }
400
- return
401
- }
402
-
403
- // x, ok = y
404
- if len (lhs ) != len (rhs ) {
405
- assert (len (lhs ) == 2 && len (rhs ) == 1 )
406
- // TODO(danscales): deal with case where x or ok is an interface
407
- // type. We want to add CONVIFACE now, but that is tricky, because
408
- // the rhs may be AS2MAPR, AS2RECV, etc. which has two result values,
409
- // and that is not rewritten until the order phase (o.stmt, as2ok).
410
- return
411
- }
412
-
413
- // Check for interface conversion on each assignment
414
- for i , r := range rhs {
415
- if lhs [i ].Type () != nil && lhs [i ].Type ().IsInterface () {
416
- rhs [i ] = assignconvfn (r , lhs [i ].Type ())
417
- }
418
- }
419
- }
420
-
421
368
// Corresponds to typecheck.typecheckargs. Really just deals with multi-value calls.
422
369
func transformArgs (n ir.InitNode ) {
423
370
var list []ir.Node
@@ -457,11 +404,11 @@ func assignconvfn(n ir.Node, t *types.Type) ir.Node {
457
404
return n
458
405
}
459
406
460
- if types .Identical (n .Type (), t ) {
407
+ if types .IdenticalStrict (n .Type (), t ) {
461
408
return n
462
409
}
463
410
464
- op , why := typecheck . Assignop (n .Type (), t )
411
+ op , why := Assignop (n .Type (), t )
465
412
if op == ir .OXXX {
466
413
base .Fatalf ("found illegal assignment %+v -> %+v; %s" , n .Type (), t , why )
467
414
}
@@ -472,11 +419,26 @@ func assignconvfn(n ir.Node, t *types.Type) ir.Node {
472
419
return r
473
420
}
474
421
422
+ func Assignop (src , dst * types.Type ) (ir.Op , string ) {
423
+ if src == dst {
424
+ return ir .OCONVNOP , ""
425
+ }
426
+ if src == nil || dst == nil || src .Kind () == types .TFORW || dst .Kind () == types .TFORW || src .Underlying () == nil || dst .Underlying () == nil {
427
+ return ir .OXXX , ""
428
+ }
429
+
430
+ // 1. src type is identical to dst.
431
+ if types .IdenticalStrict (src , dst ) {
432
+ return ir .OCONVNOP , ""
433
+ }
434
+ return typecheck .Assignop1 (src , dst )
435
+ }
436
+
475
437
// Corresponds to typecheck.typecheckaste, but we add an extra flag convifaceOnly
476
438
// only. If convifaceOnly is true, we only do interface conversion. We use this to do
477
439
// early insertion of CONVIFACE nodes during noder2, when the function or args may
478
440
// have typeparams.
479
- func typecheckaste (op ir.Op , call ir.Node , isddd bool , tstruct * types.Type , nl ir.Nodes , convifaceOnly bool ) {
441
+ func typecheckaste (op ir.Op , call ir.Node , isddd bool , tstruct * types.Type , nl ir.Nodes ) {
480
442
var t * types.Type
481
443
var i int
482
444
@@ -495,7 +457,7 @@ func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl i
495
457
if isddd {
496
458
n = nl [i ]
497
459
ir .SetPos (n )
498
- if n .Type () != nil && ( ! convifaceOnly || t . IsInterface ()) {
460
+ if n .Type () != nil {
499
461
nl [i ] = assignconvfn (n , t )
500
462
}
501
463
return
@@ -505,7 +467,7 @@ func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl i
505
467
for ; i < len (nl ); i ++ {
506
468
n = nl [i ]
507
469
ir .SetPos (n )
508
- if n .Type () != nil && ( ! convifaceOnly || t . IsInterface ()) {
470
+ if n .Type () != nil {
509
471
nl [i ] = assignconvfn (n , t .Elem ())
510
472
}
511
473
}
@@ -514,7 +476,7 @@ func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl i
514
476
515
477
n = nl [i ]
516
478
ir .SetPos (n )
517
- if n .Type () != nil && ( ! convifaceOnly || t . IsInterface ()) {
479
+ if n .Type () != nil {
518
480
nl [i ] = assignconvfn (n , t )
519
481
}
520
482
i ++
@@ -536,7 +498,7 @@ func transformReturn(rs *ir.ReturnStmt) {
536
498
return
537
499
}
538
500
539
- typecheckaste (ir .ORETURN , nil , false , ir .CurFunc .Type ().Results (), nl , false )
501
+ typecheckaste (ir .ORETURN , nil , false , ir .CurFunc .Type ().Results (), nl )
540
502
}
541
503
542
504
// transformSelect transforms a select node, creating an assignment list as needed
0 commit comments