// objDecl type-checks the declaration of obj in its respective (file) environment.
// For the meaning of def, see Checker.definedType, in typexpr.go.
-func (check *Checker) objDecl(obj Object, def *Named) {
+func (check *Checker) objDecl(obj Object, def *TypeName) {
if check.conf.Trace && obj.Type() == nil {
if check.indent == 0 {
fmt.Println() // empty line between top-level objects for readability
// the syntactic information. We should consider storing
// this information explicitly in the object.
var alias bool
- if d := check.objMap[obj]; d != nil {
- alias = d.tdecl.Alias // package-level object
+ if check.enableAlias {
+ alias = obj.IsAlias()
} else {
- alias = obj.IsAlias() // function local object
+ if d := check.objMap[obj]; d != nil {
+ alias = d.tdecl.Alias // package-level object
+ } else {
+ alias = obj.IsAlias() // function local object
+ }
}
if !alias {
ndef++
// If obj is a type alias, mark it as valid (not broken) in order to avoid follow-on errors.
tname, _ := obj.(*TypeName)
if tname != nil && tname.IsAlias() {
- check.validAlias(tname, Typ[Invalid])
+ // If we use Alias nodes, it is initialized with Typ[Invalid].
+ // TODO(gri) Adjust this code if we initialize with nil.
+ if !check.enableAlias {
+ check.validAlias(tname, Typ[Invalid])
+ }
}
// report a more concise error for self references
return u != nil && !u.IsMethodSet()
}
-func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named) {
+func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *TypeName) {
assert(obj.typ == nil)
var rhs Type
_ = check.isImportedConstraint(rhs) && check.verifyVersionf(tdecl.Type, go1_18, "using type constraint %s", rhs)
}).describef(obj, "validType(%s)", obj.Name())
- alias := tdecl.Alias
- if alias && tdecl.TParamList != nil {
+ aliasDecl := tdecl.Alias
+ if aliasDecl && tdecl.TParamList != nil {
// The parser will ensure this but we may still get an invalid AST.
// Complain and continue as regular type definition.
check.error(tdecl, BadDecl, "generic type cannot be alias")
- alias = false
+ aliasDecl = false
}
// alias declaration
- if alias {
+ if aliasDecl {
check.verifyVersionf(tdecl, go1_9, "type aliases")
- check.brokenAlias(obj)
- rhs = check.typ(tdecl.Type)
- check.validAlias(obj, rhs)
+ if check.enableAlias {
+ // TODO(gri) Should be able to use nil instead of Typ[Invalid] to mark
+ // the alias as incomplete. Currently this causes problems
+ // with certain cycles. Investigate.
+ alias := check.newAlias(obj, Typ[Invalid])
+ setDefType(def, alias)
+ rhs = check.definedType(tdecl.Type, obj)
+ assert(rhs != nil)
+ alias.fromRHS = rhs
+ Unalias(alias) // resolve alias.actual
+ } else {
+ check.brokenAlias(obj)
+ rhs = check.typ(tdecl.Type)
+ check.validAlias(obj, rhs)
+ }
return
}
// type definition or generic type declaration
named := check.newNamed(obj, nil, nil)
- def.setUnderlying(named)
+ setDefType(def, named)
if tdecl.TParamList != nil {
check.openScope(tdecl, "type parameters")
}
// determine underlying type of named
- rhs = check.definedType(tdecl.Type, named)
+ rhs = check.definedType(tdecl.Type, obj)
assert(rhs != nil)
named.fromRHS = rhs