1
0
mirror of https://github.com/golang/go synced 2024-11-25 23:07:58 -07:00

stricter rules for assignment.

when assigning a multifield object
(structs or arrays of structs) they
must not contain any fields that could
not be assigned individually.

R=ken
OCL=29192
CL=29194
This commit is contained in:
Russ Cox 2009-05-21 14:06:24 -07:00
parent b9159722dd
commit 8b6b380605
2 changed files with 79 additions and 1 deletions

View File

@ -2046,14 +2046,59 @@ loop:
goto loop; goto loop;
} }
/*
* do the export rules allow writing to this type?
* cannot be implicitly assigning to any type with
* an unavailable field.
*/
int
exportasok(Type *t)
{
Type *f;
Sym *s;
if(t == T)
return 1;
switch(t->etype) {
default:
// most types can't contain others; they're all fine.
break;
case TSTRUCT:
for(f=t->type; f; f=f->down) {
if(f->etype != TFIELD)
fatal("structas: not field");
s = f->sym;
// s == nil doesn't happen for embedded fields (they get the type symbol).
// it only happens for fields in a ... struct.
if(s != nil && !exportname(s->name) && strcmp(package, s->package) != 0) {
yyerror("implicit assignment of %T field '%s'", t, s->name);
return 0;
}
if(!exportasok(f->type))
return 0;
}
break;
case TARRAY:
if(t->bound < 0) // slices are pointers; that's fine
break;
if(!exportasok(t->type))
return 0;
break;
}
return 1;
}
/* /*
* can we assign var of type src to var of type dst * can we assign var of type src to var of type dst
*/ */
int int
ascompat(Type *dst, Type *src) ascompat(Type *dst, Type *src)
{ {
if(eqtype(dst, src)) if(eqtype(dst, src)) {
exportasok(src);
return 1; return 1;
}
if(dst == T || src == T) if(dst == T || src == T)
return 0; return 0;

33
test/assign.go Normal file
View File

@ -0,0 +1,33 @@
// errchk $G $D/$F.go
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "sync"
type T struct {
int;
sync.Mutex;
}
func main() {
{
var x, y sync.Mutex;
x = y; // ERROR "assignment.*Mutex"
}
{
var x, y T;
x = y; // ERROR "assignment.*Mutex"
}
{
var x, y [2]sync.Mutex;
x = y; // ERROR "assignment.*Mutex"
}
{
var x, y [2]T;
x = y; // ERROR "assignment.*Mutex"
}
}