mirror of
https://github.com/golang/go
synced 2024-11-22 06:34:40 -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:
parent
b9159722dd
commit
8b6b380605
@ -2046,14 +2046,59 @@ 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
|
||||
*/
|
||||
int
|
||||
ascompat(Type *dst, Type *src)
|
||||
{
|
||||
if(eqtype(dst, src))
|
||||
if(eqtype(dst, src)) {
|
||||
exportasok(src);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(dst == T || src == T)
|
||||
return 0;
|
||||
|
33
test/assign.go
Normal file
33
test/assign.go
Normal 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"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user