mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 10:11:04 +01:00
Switch static_type to return Expression& (#887)
This commit is contained in:
@@ -31,7 +31,7 @@ namespace Carbon {
|
||||
static void SetStaticType(Nonnull<Expression*> expression,
|
||||
Nonnull<const Value*> type) {
|
||||
if (expression->has_static_type()) {
|
||||
CHECK(TypeEqual(expression->static_type(), type));
|
||||
CHECK(TypeEqual(&expression->static_type(), type));
|
||||
} else {
|
||||
expression->set_static_type(type);
|
||||
}
|
||||
@@ -42,7 +42,7 @@ static void SetStaticType(Nonnull<Expression*> expression,
|
||||
static void SetStaticType(Nonnull<Pattern*> pattern,
|
||||
Nonnull<const Value*> type) {
|
||||
if (pattern->has_static_type()) {
|
||||
CHECK(TypeEqual(pattern->static_type(), type));
|
||||
CHECK(TypeEqual(&pattern->static_type(), type));
|
||||
} else {
|
||||
pattern->set_static_type(type);
|
||||
}
|
||||
@@ -53,7 +53,7 @@ static void SetStaticType(Nonnull<Pattern*> pattern,
|
||||
static void SetStaticType(Nonnull<FunctionDefinition*> definition,
|
||||
Nonnull<const Value*> type) {
|
||||
if (definition->has_static_type()) {
|
||||
CHECK(TypeEqual(definition->static_type(), type));
|
||||
CHECK(TypeEqual(&definition->static_type(), type));
|
||||
} else {
|
||||
definition->set_static_type(type);
|
||||
}
|
||||
@@ -436,18 +436,18 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
||||
case Expression::Kind::IndexExpression: {
|
||||
auto& index = cast<IndexExpression>(*e);
|
||||
auto res = TypeCheckExp(&index.aggregate(), types, values);
|
||||
Nonnull<const Value*> aggregate_type = index.aggregate().static_type();
|
||||
switch (aggregate_type->kind()) {
|
||||
const Value& aggregate_type = index.aggregate().static_type();
|
||||
switch (aggregate_type.kind()) {
|
||||
case Value::Kind::TupleValue: {
|
||||
auto i =
|
||||
cast<IntValue>(*interpreter.InterpExp(values, &index.offset()))
|
||||
.Val();
|
||||
std::string f = std::to_string(i);
|
||||
std::optional<Nonnull<const Value*>> field_t =
|
||||
cast<TupleValue>(*aggregate_type).FindField(f);
|
||||
cast<TupleValue>(aggregate_type).FindField(f);
|
||||
if (!field_t) {
|
||||
FATAL_COMPILATION_ERROR(e->source_loc())
|
||||
<< "field " << f << " is not in the tuple " << *aggregate_type;
|
||||
<< "field " << f << " is not in the tuple " << aggregate_type;
|
||||
}
|
||||
SetStaticType(&index, *field_t);
|
||||
return TCResult(res.types);
|
||||
@@ -465,7 +465,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
||||
new_types = arg_res.types;
|
||||
new_args.push_back(FieldInitializer(arg.name(), &arg.expression()));
|
||||
arg_types.push_back(
|
||||
{.name = arg.name(), .value = arg.expression().static_type()});
|
||||
{.name = arg.name(), .value = &arg.expression().static_type()});
|
||||
}
|
||||
SetStaticType(e, arena->New<TupleValue>(std::move(arg_types)));
|
||||
return TCResult(new_types);
|
||||
@@ -478,7 +478,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
||||
auto arg_res = TypeCheckExp(&arg.expression(), new_types, values);
|
||||
new_types = arg_res.types;
|
||||
new_args.push_back(FieldInitializer(arg.name(), &arg.expression()));
|
||||
arg_types.push_back({arg.name(), arg.expression().static_type()});
|
||||
arg_types.push_back({arg.name(), &arg.expression().static_type()});
|
||||
}
|
||||
SetStaticType(e, arena->New<StructType>(std::move(arg_types)));
|
||||
return TCResult(new_types);
|
||||
@@ -508,10 +508,10 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
||||
case Expression::Kind::FieldAccessExpression: {
|
||||
auto& access = cast<FieldAccessExpression>(*e);
|
||||
auto res = TypeCheckExp(&access.aggregate(), types, values);
|
||||
Nonnull<const Value*> aggregate_type = access.aggregate().static_type();
|
||||
switch (aggregate_type->kind()) {
|
||||
const Value& aggregate_type = access.aggregate().static_type();
|
||||
switch (aggregate_type.kind()) {
|
||||
case Value::Kind::StructType: {
|
||||
const auto& struct_type = cast<StructType>(*aggregate_type);
|
||||
const auto& struct_type = cast<StructType>(aggregate_type);
|
||||
for (const auto& [field_name, field_type] : struct_type.fields()) {
|
||||
if (access.field() == field_name) {
|
||||
SetStaticType(&access, field_type);
|
||||
@@ -523,7 +523,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
||||
<< access.field();
|
||||
}
|
||||
case Value::Kind::NominalClassType: {
|
||||
const auto& t_class = cast<NominalClassType>(*aggregate_type);
|
||||
const auto& t_class = cast<NominalClassType>(aggregate_type);
|
||||
// Search for a field
|
||||
for (auto& field : t_class.Fields()) {
|
||||
if (access.field() == field.first) {
|
||||
@@ -543,7 +543,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
||||
<< access.field();
|
||||
}
|
||||
case Value::Kind::TupleValue: {
|
||||
const auto& tup = cast<TupleValue>(*aggregate_type);
|
||||
const auto& tup = cast<TupleValue>(aggregate_type);
|
||||
for (const TupleElement& field : tup.Elements()) {
|
||||
if (access.field() == field.name) {
|
||||
SetStaticType(&access, field.value);
|
||||
@@ -555,12 +555,12 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
||||
<< access.field();
|
||||
}
|
||||
case Value::Kind::ChoiceType: {
|
||||
const auto& choice = cast<ChoiceType>(*aggregate_type);
|
||||
const auto& choice = cast<ChoiceType>(aggregate_type);
|
||||
for (const auto& vt : choice.Alternatives()) {
|
||||
if (access.field() == vt.first) {
|
||||
SetStaticType(&access, arena->New<FunctionType>(
|
||||
std::vector<GenericBinding>(),
|
||||
vt.second, aggregate_type));
|
||||
vt.second, &aggregate_type));
|
||||
return TCResult(res.types);
|
||||
}
|
||||
}
|
||||
@@ -600,7 +600,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
||||
auto res = TypeCheckExp(argument, types, values);
|
||||
new_types = res.types;
|
||||
es.push_back(argument);
|
||||
ts.push_back(argument->static_type());
|
||||
ts.push_back(&argument->static_type());
|
||||
}
|
||||
switch (op.op()) {
|
||||
case Operator::Neg:
|
||||
@@ -665,17 +665,16 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
||||
case Expression::Kind::CallExpression: {
|
||||
auto& call = cast<CallExpression>(*e);
|
||||
auto fun_res = TypeCheckExp(&call.function(), types, values);
|
||||
switch (call.function().static_type()->kind()) {
|
||||
switch (call.function().static_type().kind()) {
|
||||
case Value::Kind::FunctionType: {
|
||||
const auto& fun_t =
|
||||
cast<FunctionType>(*call.function().static_type());
|
||||
const auto& fun_t = cast<FunctionType>(call.function().static_type());
|
||||
auto arg_res = TypeCheckExp(&call.argument(), fun_res.types, values);
|
||||
auto parameter_type = fun_t.Param();
|
||||
auto return_type = fun_t.Ret();
|
||||
if (!fun_t.Deduced().empty()) {
|
||||
auto deduced_args = ArgumentDeduction(
|
||||
e->source_loc(), TypeEnv(arena), parameter_type,
|
||||
call.argument().static_type());
|
||||
&call.argument().static_type());
|
||||
for (auto& deduced_param : fun_t.Deduced()) {
|
||||
// TODO: change the following to a CHECK once the real checking
|
||||
// has been added to the type checking of function signatures.
|
||||
@@ -689,7 +688,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e, TypeEnv types,
|
||||
return_type = Substitute(deduced_args, return_type);
|
||||
} else {
|
||||
ExpectType(e->source_loc(), "call", parameter_type,
|
||||
call.argument().static_type());
|
||||
&call.argument().static_type());
|
||||
}
|
||||
SetStaticType(&call, return_type);
|
||||
return TCResult(arg_res.types);
|
||||
@@ -808,7 +807,7 @@ auto TypeChecker::TypeCheckPattern(
|
||||
new_types = field_result.types;
|
||||
new_fields.push_back(TuplePattern::Field(field.name, field.pattern));
|
||||
field_types.push_back(
|
||||
{.name = field.name, .value = field.pattern->static_type()});
|
||||
{.name = field.name, .value = &field.pattern->static_type()});
|
||||
}
|
||||
SetStaticType(&tuple, arena->New<TupleValue>(std::move(field_types)));
|
||||
return TCResult(new_types);
|
||||
@@ -841,7 +840,7 @@ auto TypeChecker::TypeCheckPattern(
|
||||
case Pattern::Kind::ExpressionPattern: {
|
||||
const auto& expression = cast<ExpressionPattern>(*p).Expression();
|
||||
TCResult result = TypeCheckExp(expression, types, values);
|
||||
SetStaticType(p, expression->static_type());
|
||||
SetStaticType(p, &expression->static_type());
|
||||
return TCResult(result.types);
|
||||
}
|
||||
}
|
||||
@@ -868,7 +867,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
||||
std::vector<Match::Clause> new_clauses;
|
||||
for (auto& clause : match.clauses()) {
|
||||
new_clauses.push_back(TypeCheckCase(
|
||||
match.expression().static_type(), &clause.pattern(),
|
||||
&match.expression().static_type(), &clause.pattern(),
|
||||
&clause.statement(), types, values, return_type_context));
|
||||
}
|
||||
return TCResult(types);
|
||||
@@ -877,7 +876,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
||||
auto& while_stmt = cast<While>(*s);
|
||||
TypeCheckExp(while_stmt.Cond(), types, values);
|
||||
ExpectType(s->source_loc(), "condition of `while`",
|
||||
arena->New<BoolType>(), while_stmt.Cond()->static_type());
|
||||
arena->New<BoolType>(), &while_stmt.Cond()->static_type());
|
||||
TypeCheckStmt(while_stmt.Body(), types, values, return_type_context);
|
||||
return TCResult(types);
|
||||
}
|
||||
@@ -896,8 +895,8 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
||||
case Statement::Kind::VariableDefinition: {
|
||||
auto& var = cast<VariableDefinition>(*s);
|
||||
TypeCheckExp(var.Init(), types, values);
|
||||
Nonnull<const Value*> rhs_ty = var.Init()->static_type();
|
||||
auto lhs_res = TypeCheckPattern(var.Pat(), types, values, rhs_ty);
|
||||
const Value& rhs_ty = var.Init()->static_type();
|
||||
auto lhs_res = TypeCheckPattern(var.Pat(), types, values, &rhs_ty);
|
||||
return TCResult(lhs_res.types);
|
||||
}
|
||||
case Statement::Kind::Sequence: {
|
||||
@@ -916,8 +915,8 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
||||
auto& assign = cast<Assign>(*s);
|
||||
TypeCheckExp(assign.Rhs(), types, values);
|
||||
auto lhs_res = TypeCheckExp(assign.Lhs(), types, values);
|
||||
ExpectType(s->source_loc(), "assign", assign.Lhs()->static_type(),
|
||||
assign.Rhs()->static_type());
|
||||
ExpectType(s->source_loc(), "assign", &assign.Lhs()->static_type(),
|
||||
&assign.Rhs()->static_type());
|
||||
return TCResult(lhs_res.types);
|
||||
}
|
||||
case Statement::Kind::ExpressionStatement: {
|
||||
@@ -928,7 +927,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
||||
auto& if_stmt = cast<If>(*s);
|
||||
TypeCheckExp(if_stmt.Cond(), types, values);
|
||||
ExpectType(s->source_loc(), "condition of `if`", arena->New<BoolType>(),
|
||||
if_stmt.Cond()->static_type());
|
||||
&if_stmt.Cond()->static_type());
|
||||
TypeCheckStmt(if_stmt.ThenStmt(), types, values, return_type_context);
|
||||
if (if_stmt.ElseStmt()) {
|
||||
TypeCheckStmt(*if_stmt.ElseStmt(), types, values, return_type_context);
|
||||
@@ -947,12 +946,12 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
||||
} else {
|
||||
// Infer the auto return from the first `return` statement.
|
||||
return_type_context->set_deduced_return_type(
|
||||
ret.Exp()->static_type());
|
||||
&ret.Exp()->static_type());
|
||||
}
|
||||
} else {
|
||||
ExpectType(s->source_loc(), "return",
|
||||
*return_type_context->deduced_return_type(),
|
||||
ret.Exp()->static_type());
|
||||
&ret.Exp()->static_type());
|
||||
}
|
||||
if (ret.IsOmittedExp() != return_type_context->is_omitted()) {
|
||||
FATAL_COMPILATION_ERROR(s->source_loc())
|
||||
@@ -972,7 +971,8 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s, TypeEnv types,
|
||||
auto& run = cast<Run>(*s);
|
||||
TypeCheckExp(run.Argument(), types, values);
|
||||
ExpectType(s->source_loc(), "argument of `run`",
|
||||
arena->New<ContinuationType>(), run.Argument()->static_type());
|
||||
arena->New<ContinuationType>(),
|
||||
&run.Argument()->static_type());
|
||||
return TCResult(types);
|
||||
}
|
||||
case Statement::Kind::Await: {
|
||||
@@ -1094,7 +1094,7 @@ auto TypeChecker::TypeCheckFunDef(FunctionDefinition* f, TypeEnv types,
|
||||
}
|
||||
ExpectIsConcreteType(f->return_type().source_loc(), return_type);
|
||||
SetStaticType(f, arena->New<FunctionType>(f->deduced_parameters(),
|
||||
f->param_pattern().static_type(),
|
||||
&f->param_pattern().static_type(),
|
||||
return_type));
|
||||
return TCResult(types);
|
||||
}
|
||||
@@ -1116,10 +1116,10 @@ auto TypeChecker::TypeOfFunDef(TypeEnv types, Env values,
|
||||
if (ret->kind() == Value::Kind::AutoType) {
|
||||
// FIXME do this unconditionally?
|
||||
TypeCheckFunDef(fun_def, types, values);
|
||||
return fun_def->static_type();
|
||||
return &fun_def->static_type();
|
||||
}
|
||||
return arena->New<FunctionType>(fun_def->deduced_parameters(),
|
||||
fun_def->param_pattern().static_type(), ret);
|
||||
&fun_def->param_pattern().static_type(), ret);
|
||||
}
|
||||
|
||||
auto TypeChecker::TypeOfClassDef(const ClassDefinition* sd, TypeEnv /*types*/,
|
||||
@@ -1200,7 +1200,7 @@ void TypeChecker::TypeCheck(Nonnull<Declaration*> d, const TypeEnv& types,
|
||||
Nonnull<const Value*> declared_type =
|
||||
interpreter.InterpExp(values, binding_type->Expression());
|
||||
ExpectType(var.source_loc(), "initializer of variable", declared_type,
|
||||
var.initializer().static_type());
|
||||
&var.initializer().static_type());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user