|
|
@@ -5200,9 +5200,24 @@ auto TypeChecker::DeclareClassDeclaration(Nonnull<ClassDeclaration*> class_decl,
|
|
|
*trace_stream_ << "** declaring class " << class_decl->name() << "\n";
|
|
|
}
|
|
|
Nonnull<SelfDeclaration*> self = class_decl->self();
|
|
|
-
|
|
|
ImplScope class_scope(scope_info.innermost_scope);
|
|
|
|
|
|
+ // The base class and member declarations may refer to the class, so we must
|
|
|
+ // set the static type before we start processing them. We can't set the
|
|
|
+ // constant value until later, but the base class declaration doesn't need it.
|
|
|
+ self->set_static_type(arena_->New<TypeType>());
|
|
|
+ std::optional<Nonnull<ParameterizedEntityName*>> param_name;
|
|
|
+ if (class_decl->type_params().has_value()) {
|
|
|
+ // TODO: The `enclosing_bindings` should be tracked in the parameterized
|
|
|
+ // entity name so that they can be included in the eventual type.
|
|
|
+ param_name = arena_->New<ParameterizedEntityName>(
|
|
|
+ class_decl, *class_decl->type_params());
|
|
|
+ class_decl->set_static_type(
|
|
|
+ arena_->New<TypeOfParameterizedEntityName>(*param_name));
|
|
|
+ } else {
|
|
|
+ class_decl->set_static_type(&self->static_type());
|
|
|
+ }
|
|
|
+
|
|
|
// Find base class declaration, if any. Verify that is before any data member
|
|
|
// declarations, and there is at most one.
|
|
|
std::optional<Nonnull<const NominalClassType*>> base_class;
|
|
|
@@ -5235,6 +5250,9 @@ auto TypeChecker::DeclareClassDeclaration(Nonnull<ClassDeclaration*> class_decl,
|
|
|
<< "`. Only simple classes are currently supported as base "
|
|
|
"class.";
|
|
|
}
|
|
|
+ CARBON_RETURN_IF_ERROR(ExpectCompleteType(base_class_expr->source_loc(),
|
|
|
+ "base class declaration",
|
|
|
+ base_type));
|
|
|
|
|
|
base_class = cast<NominalClassType>(base_type);
|
|
|
if (base_class.value()->declaration().extensibility() ==
|
|
|
@@ -5356,23 +5374,13 @@ auto TypeChecker::DeclareClassDeclaration(Nonnull<ClassDeclaration*> class_decl,
|
|
|
Nonnull<NominalClassType*> self_type = arena_->New<NominalClassType>(
|
|
|
class_decl, Bindings::SymbolicIdentity(arena_, bindings), base_class,
|
|
|
std::move(class_vtable));
|
|
|
- self->set_static_type(arena_->New<TypeType>());
|
|
|
self->set_constant_value(self_type);
|
|
|
|
|
|
// The declarations of the members may refer to the class, so we must set the
|
|
|
- // constant value of the class and its static type before we start processing
|
|
|
- // the members.
|
|
|
- if (class_decl->type_params().has_value()) {
|
|
|
- // TODO: The `enclosing_bindings` should be tracked in the parameterized
|
|
|
- // entity name so that they can be included in the eventual type.
|
|
|
- Nonnull<ParameterizedEntityName*> param_name =
|
|
|
- arena_->New<ParameterizedEntityName>(class_decl,
|
|
|
- *class_decl->type_params());
|
|
|
- class_decl->set_static_type(
|
|
|
- arena_->New<TypeOfParameterizedEntityName>(param_name));
|
|
|
- class_decl->set_constant_value(param_name);
|
|
|
+ // constant value of the class before we start processing the members.
|
|
|
+ if (param_name.has_value()) {
|
|
|
+ class_decl->set_constant_value(*param_name);
|
|
|
} else {
|
|
|
- class_decl->set_static_type(&self->static_type());
|
|
|
class_decl->set_constant_value(self_type);
|
|
|
}
|
|
|
|