mirror of
https://github.com/golang/go
synced 2024-11-25 03:47:57 -07:00
gc: don't print implicit type on struct literal in export
As pointed out in the discussion around 2678. R=rsc CC=golang-dev https://golang.org/cl/5534077
This commit is contained in:
parent
fb86bbe239
commit
419c53af30
@ -1150,10 +1150,15 @@ exprfmt(Fmt *f, Node *n, int prec)
|
|||||||
return fmtprint(f, "%N{ %,H }", n->right, n->list);
|
return fmtprint(f, "%N{ %,H }", n->right, n->list);
|
||||||
|
|
||||||
case OPTRLIT:
|
case OPTRLIT:
|
||||||
|
if (fmtmode == FExp && n->left->right->implicit == Implicit)
|
||||||
|
return fmtprint(f, "%N", n->left);
|
||||||
return fmtprint(f, "&%N", n->left);
|
return fmtprint(f, "&%N", n->left);
|
||||||
|
|
||||||
case OSTRUCTLIT:
|
case OSTRUCTLIT:
|
||||||
if (fmtmode == FExp) { // requires special handling of field names
|
if (fmtmode == FExp) { // requires special handling of field names
|
||||||
|
if(n->right->implicit == Implicit)
|
||||||
|
fmtstrcpy(f, "{");
|
||||||
|
else
|
||||||
fmtprint(f, "%T{", n->type);
|
fmtprint(f, "%T{", n->type);
|
||||||
for(l=n->list; l; l=l->next) {
|
for(l=n->list; l; l=l->next) {
|
||||||
// another special case: if n->left is an embedded field of builtin type,
|
// another special case: if n->left is an embedded field of builtin type,
|
||||||
@ -1411,7 +1416,7 @@ nodedump(Fmt *fp, Node *n)
|
|||||||
fmtprint(fp, "%O-%O%J", n->op, n->etype, n);
|
fmtprint(fp, "%O-%O%J", n->op, n->etype, n);
|
||||||
break;
|
break;
|
||||||
case OTYPE:
|
case OTYPE:
|
||||||
fmtprint(fp, "%O %S type=%T", n->op, n->sym, n->type);
|
fmtprint(fp, "%O %S%J type=%T", n->op, n->sym, n, n->type);
|
||||||
if(recur && n->type == T && n->ntype) {
|
if(recur && n->type == T && n->ntype) {
|
||||||
indent(fp);
|
indent(fp);
|
||||||
fmtprint(fp, "%O-ntype%N", n->op, n->ntype);
|
fmtprint(fp, "%O-ntype%N", n->op, n->ntype);
|
||||||
|
@ -217,6 +217,13 @@ enum
|
|||||||
EscNever,
|
EscNever,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Explicit,
|
||||||
|
Implicit, // don't print in output
|
||||||
|
ImplPtr, // OIND added by &T{ ... } literal
|
||||||
|
};
|
||||||
|
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
// Tree structure.
|
// Tree structure.
|
||||||
@ -252,7 +259,7 @@ struct Node
|
|||||||
uchar used;
|
uchar used;
|
||||||
uchar isddd;
|
uchar isddd;
|
||||||
uchar readonly;
|
uchar readonly;
|
||||||
uchar implicit; // don't show in printout
|
uchar implicit; // Explicit, Implicit, ImplPtr.
|
||||||
uchar addrtaken; // address taken, even if not moved to heap
|
uchar addrtaken; // address taken, even if not moved to heap
|
||||||
uchar dupok; // duplicate definitions ok (for func)
|
uchar dupok; // duplicate definitions ok (for func)
|
||||||
|
|
||||||
|
@ -808,7 +808,7 @@ uexpr:
|
|||||||
// Special case for &T{...}: turn into (*T){...}.
|
// Special case for &T{...}: turn into (*T){...}.
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
$$->right = nod(OIND, $$->right, N);
|
$$->right = nod(OIND, $$->right, N);
|
||||||
$$->right->implicit = 1;
|
$$->right->implicit = ImplPtr;
|
||||||
} else {
|
} else {
|
||||||
$$ = nod(OADDR, $2, N);
|
$$ = nod(OADDR, $2, N);
|
||||||
}
|
}
|
||||||
|
@ -2047,10 +2047,9 @@ typecheckcomplit(Node **np)
|
|||||||
n->type = t;
|
n->type = t;
|
||||||
|
|
||||||
if(isptr[t->etype]) {
|
if(isptr[t->etype]) {
|
||||||
// For better or worse, we don't allow pointers as
|
// For better or worse, we don't allow pointers as the composite literal type,
|
||||||
// the composite literal type, except when using
|
// except when using the &T syntax, which sets implicit to ImplPtr.
|
||||||
// the &T syntax, which sets implicit.
|
if(n->right->implicit == Explicit) {
|
||||||
if(!n->right->implicit) {
|
|
||||||
yyerror("invalid pointer type %T for composite literal (use &%T instead)", t, t->type);
|
yyerror("invalid pointer type %T for composite literal (use &%T instead)", t, t->type);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -3232,7 +3232,7 @@ yyreduce:
|
|||||||
// Special case for &T{...}: turn into (*T){...}.
|
// Special case for &T{...}: turn into (*T){...}.
|
||||||
(yyval.node) = (yyvsp[(2) - (2)].node);
|
(yyval.node) = (yyvsp[(2) - (2)].node);
|
||||||
(yyval.node)->right = nod(OIND, (yyval.node)->right, N);
|
(yyval.node)->right = nod(OIND, (yyval.node)->right, N);
|
||||||
(yyval.node)->right->implicit = 1;
|
(yyval.node)->right->implicit = ImplPtr;
|
||||||
} else {
|
} else {
|
||||||
(yyval.node) = nod(OADDR, (yyvsp[(2) - (2)].node), N);
|
(yyval.node) = nod(OADDR, (yyvsp[(2) - (2)].node), N);
|
||||||
}
|
}
|
||||||
|
@ -20,3 +20,22 @@ func F3() (ret []int) { return append(ret, 1) }
|
|||||||
// Call of inlined method with blank receiver.
|
// Call of inlined method with blank receiver.
|
||||||
func (_ *T) M() int { return 1 }
|
func (_ *T) M() int { return 1 }
|
||||||
func (t *T) MM() int { return t.M() }
|
func (t *T) MM() int { return t.M() }
|
||||||
|
|
||||||
|
|
||||||
|
// One more like issue 2678
|
||||||
|
type S struct { x, y int }
|
||||||
|
type U []S
|
||||||
|
|
||||||
|
func F4(S int) U { return U{{S,S}} }
|
||||||
|
|
||||||
|
func F5() []*S {
|
||||||
|
return []*S{ {1,2}, { 3, 4} }
|
||||||
|
}
|
||||||
|
|
||||||
|
func F6(S int) *U {
|
||||||
|
return &U{{S,S}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ func use() {
|
|||||||
one.F1(nil)
|
one.F1(nil)
|
||||||
one.F2(nil)
|
one.F2(nil)
|
||||||
one.F3()
|
one.F3()
|
||||||
|
one.F4(1)
|
||||||
|
|
||||||
var t *one.T
|
var t *one.T
|
||||||
t.M()
|
t.M()
|
||||||
|
Loading…
Reference in New Issue
Block a user