return eqtype1(t1, t2, 0, 1);
}
+/*
+ * can we convert from type src to dst with
+ * a trivial conversion (no bits changing)?
+ */
int
-cvttype(Type *t1, Type *t2)
+cvttype(Type *dst, Type *src)
{
- return eqtype1(t1, t2, 0, 0);
+ Sym *ds, *ss;
+ int ret;
+
+ if(eqtype1(dst, src, 0, 0))
+ return 1;
+
+ // Can convert if assignment compatible when
+ // top-level names are ignored.
+ ds = dst->sym;
+ dst->sym = nil;
+ ss = src->sym;
+ src->sym = nil;
+ ret = ascompat(dst, src);
+ dst->sym = ds;
+ src->sym = ss;
+ return ret == 1;
}
int
return;
// no-op conversion
- if(cvttype(t, l->type)) {
+ if(cvttype(t, l->type) == 1) {
nop:
if(l->op != ONAME) {
indir(n, l);
}
/*
- * can we assign var of type src to var of type dst
+ * can we assign var of type src to var of type dst?
+ * return 0 if not, 1 if conversion is trivial, 2 if conversion is non-trivial.
*/
int
ascompat(Type *dst, Type *src)
if(dst == T || src == T)
return 0;
+ if(dst->etype == TFORWINTER || dst->etype == TFORWSTRUCT || dst->etype == TFORW)
+ return 0;
+ if(src->etype == TFORWINTER || src->etype == TFORWSTRUCT || src->etype == TFORW)
+ return 0;
+
+ // interfaces go through even if names don't match
+ if(isnilinter(dst) || isnilinter(src))
+ return 2;
+
+ if(isinter(dst) && isinter(src))
+ return 2;
+
+ if(isinter(dst) && methtype(src))
+ return 2;
+
+ if(isinter(src) && methtype(dst))
+ return 2;
+
+ // otherwise, if concrete types have names, they must match
+ if(dst->sym && src->sym && dst != src)
+ return 0;
+
if(dst->etype == TCHAN && src->etype == TCHAN) {
if(!eqtype(dst->type, src->type))
return 0;
&& isptr[src->etype]
&& isfixedarray(src->type)
&& eqtype(dst->type, src->type->type))
- return 1;
-
- if(isnilinter(dst) || isnilinter(src))
- return 1;
-
- if(isinter(dst) && isinter(src))
- return 1;
-
- if(isinter(dst) && methtype(src))
- return 1;
-
- if(isinter(src) && methtype(dst))
- return 1;
+ return 2;
return 0;
}