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:
parent
b9159722dd
commit
8b6b380605
@ -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
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