|
|
@@ -55,9 +55,8 @@ struct TypeChecker::SingleStepEqualityContext : public EqualityContext {
|
|
|
if (impl_witness) {
|
|
|
return impl_witness;
|
|
|
}
|
|
|
- return CompilationError(source_loc)
|
|
|
- << "value of associated constant " << *assoc
|
|
|
- << " depends on a generic parameter";
|
|
|
+ return ProgramError(source_loc) << "value of associated constant " << *assoc
|
|
|
+ << " depends on a generic parameter";
|
|
|
}
|
|
|
|
|
|
// Visits the values that are equal to the given value and a single step away
|
|
|
@@ -139,9 +138,9 @@ auto TypeChecker::ExpectExactType(SourceLocation source_loc,
|
|
|
const ImplScope& impl_scope) const
|
|
|
-> ErrorOr<Success> {
|
|
|
if (!IsSameType(expected, actual, impl_scope)) {
|
|
|
- return CompilationError(source_loc) << "type error in " << context << "\n"
|
|
|
- << "expected: " << *expected << "\n"
|
|
|
- << "actual: " << *actual;
|
|
|
+ return ProgramError(source_loc) << "type error in " << context << "\n"
|
|
|
+ << "expected: " << *expected << "\n"
|
|
|
+ << "actual: " << *actual;
|
|
|
}
|
|
|
return Success();
|
|
|
}
|
|
|
@@ -152,9 +151,9 @@ static auto ExpectPointerType(SourceLocation source_loc,
|
|
|
-> ErrorOr<Success> {
|
|
|
// TODO: Try to resolve in equality context.
|
|
|
if (actual->kind() != Value::Kind::PointerType) {
|
|
|
- return CompilationError(source_loc) << "type error in " << context << "\n"
|
|
|
- << "expected a pointer type\n"
|
|
|
- << "actual: " << *actual;
|
|
|
+ return ProgramError(source_loc) << "type error in " << context << "\n"
|
|
|
+ << "expected a pointer type\n"
|
|
|
+ << "actual: " << *actual;
|
|
|
}
|
|
|
return Success();
|
|
|
}
|
|
|
@@ -307,8 +306,7 @@ auto TypeChecker::ExpectIsType(SourceLocation source_loc,
|
|
|
Nonnull<const Value*> value)
|
|
|
-> ErrorOr<Success> {
|
|
|
if (!IsType(value)) {
|
|
|
- return CompilationError(source_loc)
|
|
|
- << "Expected a type, but got " << *value;
|
|
|
+ return ProgramError(source_loc) << "Expected a type, but got " << *value;
|
|
|
} else {
|
|
|
return Success();
|
|
|
}
|
|
|
@@ -324,8 +322,7 @@ auto TypeChecker::ExpectIsConcreteType(SourceLocation source_loc,
|
|
|
Nonnull<const Value*> value)
|
|
|
-> ErrorOr<Success> {
|
|
|
if (!IsConcreteType(value)) {
|
|
|
- return CompilationError(source_loc)
|
|
|
- << "Expected a type, but got " << *value;
|
|
|
+ return ProgramError(source_loc) << "Expected a type, but got " << *value;
|
|
|
} else {
|
|
|
return Success();
|
|
|
}
|
|
|
@@ -543,7 +540,7 @@ auto TypeChecker::ImplicitlyConvert(const std::string& context,
|
|
|
BuiltinMethodCall{"Convert"});
|
|
|
if (!converted.ok()) {
|
|
|
// We couldn't find a matching `impl`.
|
|
|
- return CompilationError(source->source_loc())
|
|
|
+ return ProgramError(source->source_loc())
|
|
|
<< "type error in " << context << ": "
|
|
|
<< "'" << *source_type << "' is not implicitly convertible to '"
|
|
|
<< *destination << "'";
|
|
|
@@ -555,7 +552,7 @@ auto TypeChecker::GetBuiltinInterfaceType(SourceLocation source_loc,
|
|
|
BuiltinInterfaceName interface) const
|
|
|
-> ErrorOr<Nonnull<const InterfaceType*>> {
|
|
|
auto bad_builtin = [&]() -> Error {
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< "unsupported declaration for builtin `"
|
|
|
<< Builtins::GetName(interface.builtin) << "`";
|
|
|
};
|
|
|
@@ -623,7 +620,7 @@ auto TypeChecker::ExpectType(SourceLocation source_loc,
|
|
|
-> ErrorOr<Success> {
|
|
|
if (!IsImplicitlyConvertible(actual, expected, impl_scope,
|
|
|
/*allow_user_defined_conversions=*/true)) {
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< "type error in " << context << ": "
|
|
|
<< "'" << *actual << "' is not implicitly convertible to '"
|
|
|
<< *expected << "'";
|
|
|
@@ -656,9 +653,9 @@ auto TypeChecker::ArgumentDeduction(
|
|
|
// Parameter type contains a nested `auto` and argument type isn't the
|
|
|
// same kind of type.
|
|
|
// TODO: This seems like something we should be able to accept.
|
|
|
- return CompilationError(source_loc) << "type error in " << context << "\n"
|
|
|
- << "expected: " << *param << "\n"
|
|
|
- << "actual: " << *arg;
|
|
|
+ return ProgramError(source_loc) << "type error in " << context << "\n"
|
|
|
+ << "expected: " << *param << "\n"
|
|
|
+ << "actual: " << *arg;
|
|
|
}
|
|
|
const Value* subst_param_type = Substitute(deduced, param);
|
|
|
return allow_implicit_conversion
|
|
|
@@ -676,7 +673,7 @@ auto TypeChecker::ArgumentDeduction(
|
|
|
const Value* binding_type = Substitute(deduced, &binding.static_type());
|
|
|
if (!IsTypeOfType(binding_type)) {
|
|
|
if (!IsImplicitlyConvertible(arg, binding_type, impl_scope, false)) {
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< "cannot convert deduced value " << *arg << " for "
|
|
|
<< binding.name() << " to parameter type " << *binding_type;
|
|
|
}
|
|
|
@@ -693,7 +690,7 @@ auto TypeChecker::ArgumentDeduction(
|
|
|
// should be used, and we'd need to check all pairs of types for
|
|
|
// equality because our notion of equality is non-transitive.
|
|
|
if (!TypeEqual(it->second, arg, std::nullopt)) {
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< "deduced multiple different values for "
|
|
|
<< var_type.binding() << ":\n " << *it->second << "\n "
|
|
|
<< *arg;
|
|
|
@@ -711,7 +708,7 @@ auto TypeChecker::ArgumentDeduction(
|
|
|
const auto& param_tup = cast<TupleValue>(*param);
|
|
|
const auto& arg_tup = cast<TupleValue>(*arg);
|
|
|
if (param_tup.elements().size() != arg_tup.elements().size()) {
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< "mismatch in tuple sizes, expected "
|
|
|
<< param_tup.elements().size() << " but got "
|
|
|
<< arg_tup.elements().size();
|
|
|
@@ -735,7 +732,7 @@ auto TypeChecker::ArgumentDeduction(
|
|
|
bool missing_from_source) -> Error {
|
|
|
static constexpr const char* SourceOrDestination[2] = {"source",
|
|
|
"destination"};
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< "mismatch in field names, "
|
|
|
<< SourceOrDestination[missing_from_source ? 1 : 0] << " field `"
|
|
|
<< field.name << "` not in "
|
|
|
@@ -758,7 +755,7 @@ auto TypeChecker::ArgumentDeduction(
|
|
|
}
|
|
|
arg_field = arg_struct.fields()[i];
|
|
|
if (param_field.name != arg_field.name) {
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< "mismatch in field names, `" << param_field.name
|
|
|
<< "` != `" << arg_field.name << "`";
|
|
|
}
|
|
|
@@ -894,9 +891,8 @@ auto TypeChecker::ArgumentDeduction(
|
|
|
// TODO: Deduce within the values where possible.
|
|
|
// TODO: Consider in-scope value equalities here.
|
|
|
if (!ValueEqual(param, arg, std::nullopt)) {
|
|
|
- return CompilationError(source_loc)
|
|
|
- << "mismatch in non-type values, `" << *arg << "` != `" << *param
|
|
|
- << "`";
|
|
|
+ return ProgramError(source_loc) << "mismatch in non-type values, `"
|
|
|
+ << *arg << "` != `" << *param << "`";
|
|
|
}
|
|
|
return Success();
|
|
|
}
|
|
|
@@ -1352,7 +1348,7 @@ auto TypeChecker::DeduceCallBindings(
|
|
|
llvm::ArrayRef<Nonnull<const Expression*>> args =
|
|
|
cast<TupleLiteral>(call.argument()).fields();
|
|
|
if (params.size() != args.size()) {
|
|
|
- return CompilationError(call.source_loc())
|
|
|
+ return ProgramError(call.source_loc())
|
|
|
<< "wrong number of arguments in function call, expected "
|
|
|
<< params.size() << " but got " << args.size();
|
|
|
}
|
|
|
@@ -1393,7 +1389,7 @@ auto TypeChecker::DeduceCallBindings(
|
|
|
// has been added to the type checking of function signatures.
|
|
|
if (auto it = generic_bindings.find(deduced_param);
|
|
|
it == generic_bindings.end()) {
|
|
|
- return CompilationError(call.source_loc())
|
|
|
+ return ProgramError(call.source_loc())
|
|
|
<< "could not deduce type argument for type parameter "
|
|
|
<< deduced_param->name() << "\n"
|
|
|
<< "in " << call;
|
|
|
@@ -1466,7 +1462,7 @@ static auto LookupInConstraint(SourceLocation source_loc,
|
|
|
}
|
|
|
// TODO: If we resolve to the same member either way, this
|
|
|
// is not ambiguous.
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< "ambiguous " << lookup_kind << ", " << member_name
|
|
|
<< " found in " << *found->interface << " and " << iface_type;
|
|
|
}
|
|
|
@@ -1476,10 +1472,10 @@ static auto LookupInConstraint(SourceLocation source_loc,
|
|
|
|
|
|
if (!found) {
|
|
|
if (isa<TypeType>(type)) {
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< lookup_kind << " in unconstrained type";
|
|
|
}
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< lookup_kind << ", " << member_name << " not in " << *type;
|
|
|
}
|
|
|
return found.value();
|
|
|
@@ -1520,7 +1516,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
InterpExp(&index.offset(), arena_, trace_stream_));
|
|
|
int i = cast<IntValue>(*offset_value).value();
|
|
|
if (i < 0 || i >= static_cast<int>(tuple_type.elements().size())) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "index " << i << " is out of range for type "
|
|
|
<< tuple_type;
|
|
|
}
|
|
|
@@ -1539,7 +1535,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
return Success();
|
|
|
}
|
|
|
default:
|
|
|
- return CompilationError(e->source_loc()) << "expected a tuple";
|
|
|
+ return ProgramError(e->source_loc()) << "expected a tuple";
|
|
|
}
|
|
|
}
|
|
|
case ExpressionKind::TupleLiteral: {
|
|
|
@@ -1598,7 +1594,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
return Success();
|
|
|
}
|
|
|
}
|
|
|
- return CompilationError(access.source_loc())
|
|
|
+ return ProgramError(access.source_loc())
|
|
|
<< "struct " << struct_type << " does not have a field named "
|
|
|
<< access.member_name();
|
|
|
}
|
|
|
@@ -1629,7 +1625,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
e->source_loc(), "method access, receiver type", me_type,
|
|
|
&access.object().static_type(), impl_scope));
|
|
|
if (access.object().value_category() != ValueCategory::Var) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "method " << access.member_name()
|
|
|
<< " requires its receiver to be an lvalue";
|
|
|
}
|
|
|
@@ -1644,7 +1640,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
}
|
|
|
return Success();
|
|
|
} else {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "class " << t_class.declaration().name()
|
|
|
<< " does not have a field named " << access.member_name();
|
|
|
}
|
|
|
@@ -1759,7 +1755,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
return Success();
|
|
|
}
|
|
|
}
|
|
|
- return CompilationError(access.source_loc())
|
|
|
+ return ProgramError(access.source_loc())
|
|
|
<< "struct " << *type << " does not have a field named "
|
|
|
<< " does not have a field named " << access.member_name();
|
|
|
}
|
|
|
@@ -1768,7 +1764,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
std::optional<Nonnull<const Value*>> parameter_types =
|
|
|
choice.FindAlternative(access.member_name());
|
|
|
if (!parameter_types.has_value()) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "choice " << choice.name()
|
|
|
<< " does not have an alternative named "
|
|
|
<< access.member_name();
|
|
|
@@ -1819,7 +1815,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
access.set_value_category(ValueCategory::Let);
|
|
|
return Success();
|
|
|
} else {
|
|
|
- return CompilationError(access.source_loc())
|
|
|
+ return ProgramError(access.source_loc())
|
|
|
<< class_type << " does not have a member named "
|
|
|
<< access.member_name();
|
|
|
}
|
|
|
@@ -1838,12 +1834,12 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
return Success();
|
|
|
}
|
|
|
default:
|
|
|
- return CompilationError(access.source_loc())
|
|
|
+ return ProgramError(access.source_loc())
|
|
|
<< "unsupported member access into type " << *type;
|
|
|
}
|
|
|
}
|
|
|
default:
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "member access, unexpected " << object_type << " in " << *e;
|
|
|
}
|
|
|
}
|
|
|
@@ -1852,7 +1848,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
CARBON_RETURN_IF_ERROR(TypeCheckExp(&access.object(), impl_scope));
|
|
|
CARBON_RETURN_IF_ERROR(TypeCheckExp(&access.path(), impl_scope));
|
|
|
if (!isa<TypeOfMemberName>(access.path().static_type())) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "expected name of instance member or interface member in "
|
|
|
"compound member access, found "
|
|
|
<< access.path().static_type();
|
|
|
@@ -1961,7 +1957,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
cast<FunctionDeclaration>(ident.value_node().base());
|
|
|
if (!function.has_static_type()) {
|
|
|
CARBON_CHECK(function.return_term().is_auto());
|
|
|
- return CompilationError(ident.source_loc())
|
|
|
+ return ProgramError(ident.source_loc())
|
|
|
<< "Function calls itself, but has a deduced return type";
|
|
|
}
|
|
|
}
|
|
|
@@ -2003,7 +1999,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
BuiltinMethodCall{"Op"});
|
|
|
if (!result.ok()) {
|
|
|
// We couldn't find a matching `impl`.
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "type error in `" << ToString(op.op()) << "`:\n"
|
|
|
<< result.error().message();
|
|
|
}
|
|
|
@@ -2018,7 +2014,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
BuiltinMethodCall{"Op", {op.arguments()[1]}});
|
|
|
if (!result.ok()) {
|
|
|
// We couldn't find a matching `impl`.
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "type error in `" << ToString(op.op()) << "`:\n"
|
|
|
<< result.error().message();
|
|
|
}
|
|
|
@@ -2049,7 +2045,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
BuiltinMethodCall{method_name, op.arguments()[1]});
|
|
|
if (!converted.ok()) {
|
|
|
// We couldn't find a matching `impl`.
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< *ts[0] << " is not " << operator_desc << " comparable with "
|
|
|
<< *ts[1] << " (" << converted.error().message() << ")";
|
|
|
}
|
|
|
@@ -2093,7 +2089,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
dyn_cast<TypeOfConstraintType>(ts[i])) {
|
|
|
constraints[i] = &constraint_type_type->constraint_type();
|
|
|
} else {
|
|
|
- return CompilationError(op.arguments()[i]->source_loc())
|
|
|
+ return ProgramError(op.arguments()[i]->source_loc())
|
|
|
<< "argument to " << ToString(op.op())
|
|
|
<< " should be a constraint, found `" << *ts[i] << "`";
|
|
|
}
|
|
|
@@ -2170,7 +2166,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
return Success();
|
|
|
case Operator::AddressOf:
|
|
|
if (op.arguments()[0]->value_category() != ValueCategory::Var) {
|
|
|
- return CompilationError(op.arguments()[0]->source_loc())
|
|
|
+ return ProgramError(op.arguments()[0]->source_loc())
|
|
|
<< "Argument to " << ToString(op.op())
|
|
|
<< " should be an lvalue.";
|
|
|
}
|
|
|
@@ -2189,7 +2185,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
BuiltinMethodCall{"Convert"});
|
|
|
if (!converted.ok()) {
|
|
|
// We couldn't find a matching `impl`.
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "type error in `as`: `" << *ts[0]
|
|
|
<< "` is not explicitly convertible to `" << *type << "`:\n"
|
|
|
<< converted.error().message();
|
|
|
@@ -2292,7 +2288,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
}
|
|
|
case Value::Kind::TypeOfChoiceType:
|
|
|
default: {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "in call `" << *e
|
|
|
<< "`, expected callee to be a function, found `"
|
|
|
<< call.function().static_type() << "`";
|
|
|
@@ -2322,7 +2318,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
// overloads. Here, that's the name Print instead of __intrinsic_print
|
|
|
// in errors.
|
|
|
if (args.size() < 1 || args.size() > 2) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "Print takes 1 or 2 arguments, received " << args.size();
|
|
|
}
|
|
|
CARBON_RETURN_IF_ERROR(ExpectExactType(
|
|
|
@@ -2338,7 +2334,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
return Success();
|
|
|
case IntrinsicExpression::Intrinsic::Assert: {
|
|
|
if (args.size() != 2) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "__intrinsic_assert takes 2 arguments";
|
|
|
}
|
|
|
CARBON_RETURN_IF_ERROR(ExpectType(
|
|
|
@@ -2353,7 +2349,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
}
|
|
|
case IntrinsicExpression::Intrinsic::Alloc: {
|
|
|
if (args.size() != 1) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "__intrinsic_new takes 1 argument";
|
|
|
}
|
|
|
auto arg_type = &args[0]->static_type();
|
|
|
@@ -2363,7 +2359,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
}
|
|
|
case IntrinsicExpression::Intrinsic::Dealloc: {
|
|
|
if (args.size() != 1) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "__intrinsic_new takes 1 argument";
|
|
|
}
|
|
|
auto arg_type = &args[0]->static_type();
|
|
|
@@ -2375,7 +2371,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
}
|
|
|
case IntrinsicExpression::Intrinsic::Rand: {
|
|
|
if (args.size() != 2) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "Rand takes 2 arguments, received " << args.size();
|
|
|
}
|
|
|
CARBON_RETURN_IF_ERROR(ExpectExactType(
|
|
|
@@ -2392,7 +2388,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
}
|
|
|
case IntrinsicExpression::Intrinsic::IntEq: {
|
|
|
if (args.size() != 2) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "__intrinsic_int_eq takes 2 arguments";
|
|
|
}
|
|
|
CARBON_RETURN_IF_ERROR(ExpectExactType(
|
|
|
@@ -2407,7 +2403,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
}
|
|
|
case IntrinsicExpression::Intrinsic::IntCompare: {
|
|
|
if (args.size() != 2) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "__intrinsic_int_compare takes 2 arguments";
|
|
|
}
|
|
|
CARBON_RETURN_IF_ERROR(ExpectExactType(
|
|
|
@@ -2422,7 +2418,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
}
|
|
|
case IntrinsicExpression::Intrinsic::StrEq: {
|
|
|
if (args.size() != 2) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "__intrinsic_str_eq takes 2 arguments";
|
|
|
}
|
|
|
CARBON_RETURN_IF_ERROR(ExpectExactType(
|
|
|
@@ -2437,7 +2433,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
}
|
|
|
case IntrinsicExpression::Intrinsic::StrCompare: {
|
|
|
if (args.size() != 2) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "__intrinsic_str_compare takes 2 arguments";
|
|
|
}
|
|
|
CARBON_RETURN_IF_ERROR(ExpectExactType(
|
|
|
@@ -2452,7 +2448,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
}
|
|
|
case IntrinsicExpression::Intrinsic::IntBitComplement:
|
|
|
if (args.size() != 1) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< intrinsic_exp.name() << " takes 1 argument";
|
|
|
}
|
|
|
CARBON_RETURN_IF_ERROR(ExpectExactType(
|
|
|
@@ -2467,7 +2463,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
case IntrinsicExpression::Intrinsic::IntLeftShift:
|
|
|
case IntrinsicExpression::Intrinsic::IntRightShift:
|
|
|
if (args.size() != 2) {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< intrinsic_exp.name() << " takes 2 arguments";
|
|
|
}
|
|
|
CARBON_RETURN_IF_ERROR(ExpectExactType(
|
|
|
@@ -2531,7 +2527,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
} else if (isa<TypeType>(base_type)) {
|
|
|
// Start with an unconstrained type.
|
|
|
} else {
|
|
|
- return CompilationError(e->source_loc())
|
|
|
+ return ProgramError(e->source_loc())
|
|
|
<< "expected constraint as first operand of `where` expression, "
|
|
|
<< "found " << base_type;
|
|
|
}
|
|
|
@@ -2567,7 +2563,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
map[constraint_type->self_binding()] = type;
|
|
|
builder.Add(cast<ConstraintType>(Substitute(map, constraint)));
|
|
|
} else {
|
|
|
- return CompilationError(is_clause.constraint().source_loc())
|
|
|
+ return ProgramError(is_clause.constraint().source_loc())
|
|
|
<< "expression after `is` does not resolve to a "
|
|
|
"constraint, found value "
|
|
|
<< *constraint << " of type "
|
|
|
@@ -2613,7 +2609,7 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
|
|
|
Nonnull<const Value*> size_value,
|
|
|
InterpExp(&array_literal.size_expression(), arena_, trace_stream_));
|
|
|
if (cast<IntValue>(size_value)->value() < 0) {
|
|
|
- return CompilationError(array_literal.size_expression().source_loc())
|
|
|
+ return ProgramError(array_literal.size_expression().source_loc())
|
|
|
<< "Array size cannot be negative";
|
|
|
}
|
|
|
array_literal.set_static_type(arena_->New<TypeType>());
|
|
|
@@ -2693,7 +2689,7 @@ auto TypeChecker::TypeCheckWhereClause(Nonnull<WhereClause*> clause,
|
|
|
CARBON_RETURN_IF_ERROR(TypeCheckExp(&is_clause.constraint(), impl_scope));
|
|
|
if (!isa<TypeOfInterfaceType, TypeOfConstraintType, TypeType>(
|
|
|
is_clause.constraint().static_type())) {
|
|
|
- return CompilationError(is_clause.constraint().source_loc())
|
|
|
+ return ProgramError(is_clause.constraint().source_loc())
|
|
|
<< "expression after `is` does not resolve to a constraint, "
|
|
|
<< "found " << is_clause.constraint().static_type();
|
|
|
}
|
|
|
@@ -2713,7 +2709,7 @@ auto TypeChecker::TypeCheckWhereClause(Nonnull<WhereClause*> clause,
|
|
|
/*allow_user_defined_conversions=*/false) &&
|
|
|
!IsImplicitlyConvertible(rhs_type, lhs_type, impl_scope,
|
|
|
/*allow_user_defined_conversions=*/false)) {
|
|
|
- return CompilationError(clause->source_loc())
|
|
|
+ return ProgramError(clause->source_loc())
|
|
|
<< "type mismatch between values in `where LHS == RHS`\n"
|
|
|
<< " LHS type: " << *lhs_type << "\n"
|
|
|
<< " RHS type: " << *rhs_type;
|
|
|
@@ -2746,7 +2742,7 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
if (!VisitNestedPatterns(binding.type(), [](const Pattern& pattern) {
|
|
|
return !isa<BindingPattern>(pattern);
|
|
|
})) {
|
|
|
- return CompilationError(binding.type().source_loc())
|
|
|
+ return ProgramError(binding.type().source_loc())
|
|
|
<< "The type of a binding pattern cannot contain bindings.";
|
|
|
}
|
|
|
CARBON_RETURN_IF_ERROR(TypeCheckPattern(
|
|
|
@@ -2764,7 +2760,7 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
if (!PatternMatch(type, *expected, binding.type().source_loc(),
|
|
|
std::nullopt, generic_args, trace_stream_,
|
|
|
this->arena_)) {
|
|
|
- return CompilationError(binding.type().source_loc())
|
|
|
+ return ProgramError(binding.type().source_loc())
|
|
|
<< "Type pattern '" << *type
|
|
|
<< "' does not match actual type '" << **expected << "'";
|
|
|
}
|
|
|
@@ -2787,14 +2783,14 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
CARBON_ASSIGN_OR_RETURN(Nonnull<const Value*> type,
|
|
|
TypeCheckTypeExp(&binding.type(), impl_scope));
|
|
|
if (expected) {
|
|
|
- return CompilationError(binding.type().source_loc())
|
|
|
+ return ProgramError(binding.type().source_loc())
|
|
|
<< "Generic binding may not occur in pattern with expected "
|
|
|
"type: "
|
|
|
<< binding;
|
|
|
}
|
|
|
binding.set_static_type(type);
|
|
|
if (binding.named_as_type_via_dot_self() && !IsTypeOfType(type)) {
|
|
|
- return CompilationError(binding.type().source_loc())
|
|
|
+ return ProgramError(binding.type().source_loc())
|
|
|
<< "`.Self` used in type of non-type binding `" << binding.name()
|
|
|
<< "`";
|
|
|
}
|
|
|
@@ -2817,12 +2813,11 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
auto& tuple = cast<TuplePattern>(*p);
|
|
|
std::vector<Nonnull<const Value*>> field_types;
|
|
|
if (expected && (*expected)->kind() != Value::Kind::TupleValue) {
|
|
|
- return CompilationError(p->source_loc()) << "didn't expect a tuple";
|
|
|
+ return ProgramError(p->source_loc()) << "didn't expect a tuple";
|
|
|
}
|
|
|
if (expected && tuple.fields().size() !=
|
|
|
cast<TupleValue>(**expected).elements().size()) {
|
|
|
- return CompilationError(tuple.source_loc())
|
|
|
- << "tuples of different length";
|
|
|
+ return ProgramError(tuple.source_loc()) << "tuples of different length";
|
|
|
}
|
|
|
for (size_t i = 0; i < tuple.fields().size(); ++i) {
|
|
|
Nonnull<Pattern*> field = tuple.fields()[i];
|
|
|
@@ -2851,7 +2846,7 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
Nonnull<const Value*> type,
|
|
|
InterpExp(&alternative.choice_type(), arena_, trace_stream_));
|
|
|
if (!isa<ChoiceType>(type)) {
|
|
|
- return CompilationError(alternative.source_loc())
|
|
|
+ return ProgramError(alternative.source_loc())
|
|
|
<< "alternative pattern does not name a choice type.";
|
|
|
}
|
|
|
const ChoiceType& choice_type = cast<ChoiceType>(*type);
|
|
|
@@ -2863,7 +2858,7 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
std::optional<Nonnull<const Value*>> parameter_types =
|
|
|
choice_type.FindAlternative(alternative.alternative_name());
|
|
|
if (parameter_types == std::nullopt) {
|
|
|
- return CompilationError(alternative.source_loc())
|
|
|
+ return ProgramError(alternative.source_loc())
|
|
|
<< "'" << alternative.alternative_name()
|
|
|
<< "' is not an alternative of " << choice_type;
|
|
|
}
|
|
|
@@ -2919,7 +2914,7 @@ auto TypeChecker::TypeCheckPattern(
|
|
|
dyn_cast<PointerType>(&addr_pattern.binding().static_type())) {
|
|
|
addr_pattern.set_static_type(&inner_binding_type->type());
|
|
|
} else {
|
|
|
- return CompilationError(addr_pattern.source_loc())
|
|
|
+ return ProgramError(addr_pattern.source_loc())
|
|
|
<< "Type associated with addr must be a pointer type.";
|
|
|
}
|
|
|
CARBON_ASSIGN_OR_RETURN(
|
|
|
@@ -2965,7 +2960,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s,
|
|
|
expected_type = &clause.pattern().static_type();
|
|
|
}
|
|
|
if (patterns.IsRedundant({&clause.pattern()})) {
|
|
|
- return CompilationError(clause.pattern().source_loc())
|
|
|
+ return ProgramError(clause.pattern().source_loc())
|
|
|
<< "unreachable case: all values matched by this case "
|
|
|
<< "are matched by earlier cases";
|
|
|
}
|
|
|
@@ -3009,7 +3004,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s,
|
|
|
inner_impl_scope, ValueCategory::Var));
|
|
|
|
|
|
} else {
|
|
|
- return CompilationError(for_stmt.source_loc())
|
|
|
+ return ProgramError(for_stmt.source_loc())
|
|
|
<< "expected array type after in, found value of type " << rhs;
|
|
|
}
|
|
|
|
|
|
@@ -3058,7 +3053,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s,
|
|
|
CARBON_RETURN_IF_ERROR(TypeCheckExp(&assign.rhs(), impl_scope));
|
|
|
CARBON_RETURN_IF_ERROR(TypeCheckExp(&assign.lhs(), impl_scope));
|
|
|
if (assign.lhs().value_category() != ValueCategory::Var) {
|
|
|
- return CompilationError(assign.source_loc())
|
|
|
+ return ProgramError(assign.source_loc())
|
|
|
<< "Cannot assign to rvalue '" << assign.lhs() << "'";
|
|
|
}
|
|
|
CARBON_ASSIGN_OR_RETURN(
|
|
|
@@ -3099,7 +3094,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s,
|
|
|
CARBON_CHECK(IsConcreteType(&ret.value_node().static_type()));
|
|
|
if (!IsSameType(&return_term.static_type(),
|
|
|
&ret.value_node().static_type(), impl_scope)) {
|
|
|
- return CompilationError(ret.value_node().base().source_loc())
|
|
|
+ return ProgramError(ret.value_node().base().source_loc())
|
|
|
<< "type of returned var `" << ret.value_node().static_type()
|
|
|
<< "` does not match return type `"
|
|
|
<< return_term.static_type() << "`";
|
|
|
@@ -3159,7 +3154,7 @@ auto TypeChecker::ExpectReturnOnAllPaths(
|
|
|
std::optional<Nonnull<Statement*>> opt_stmt, SourceLocation source_loc)
|
|
|
-> ErrorOr<Success> {
|
|
|
if (!opt_stmt) {
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< "control-flow reaches end of function that provides a `->` "
|
|
|
"return type without reaching a return statement";
|
|
|
}
|
|
|
@@ -3168,7 +3163,7 @@ auto TypeChecker::ExpectReturnOnAllPaths(
|
|
|
case StatementKind::Match: {
|
|
|
auto& match = cast<Match>(*stmt);
|
|
|
if (!IsExhaustive(match)) {
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< "non-exhaustive match may allow control-flow to reach the "
|
|
|
"end "
|
|
|
"of a function that provides a `->` return type";
|
|
|
@@ -3183,7 +3178,7 @@ auto TypeChecker::ExpectReturnOnAllPaths(
|
|
|
case StatementKind::Block: {
|
|
|
auto& block = cast<Block>(*stmt);
|
|
|
if (block.statements().empty()) {
|
|
|
- return CompilationError(stmt->source_loc())
|
|
|
+ return ProgramError(stmt->source_loc())
|
|
|
<< "control-flow reaches end of function that provides a `->` "
|
|
|
"return type without reaching a return statement";
|
|
|
}
|
|
|
@@ -3213,7 +3208,7 @@ auto TypeChecker::ExpectReturnOnAllPaths(
|
|
|
case StatementKind::Break:
|
|
|
case StatementKind::Continue:
|
|
|
case StatementKind::VariableDefinition:
|
|
|
- return CompilationError(stmt->source_loc())
|
|
|
+ return ProgramError(stmt->source_loc())
|
|
|
<< "control-flow reaches end of function that provides a `->` "
|
|
|
"return type without reaching a return statement";
|
|
|
}
|
|
|
@@ -3279,7 +3274,7 @@ auto TypeChecker::DeclareCallableDeclaration(Nonnull<CallableDeclaration*> f,
|
|
|
} else {
|
|
|
// We have to type-check the body in order to determine the return type.
|
|
|
if (!f->body().has_value()) {
|
|
|
- return CompilationError(f->return_term().source_loc())
|
|
|
+ return ProgramError(f->return_term().source_loc())
|
|
|
<< "Function declaration has deduced return type but no body";
|
|
|
}
|
|
|
CARBON_RETURN_IF_ERROR(TypeCheckStmt(*f->body(), function_scope));
|
|
|
@@ -3311,7 +3306,7 @@ auto TypeChecker::DeclareCallableDeclaration(Nonnull<CallableDeclaration*> f,
|
|
|
|
|
|
if (f->name() == "Main") {
|
|
|
if (!f->return_term().type_expression().has_value()) {
|
|
|
- return CompilationError(f->return_term().source_loc())
|
|
|
+ return ProgramError(f->return_term().source_loc())
|
|
|
<< "`Main` must have an explicit return type";
|
|
|
}
|
|
|
CARBON_RETURN_IF_ERROR(
|
|
|
@@ -3368,11 +3363,11 @@ auto TypeChecker::DeclareClassDeclaration(Nonnull<ClassDeclaration*> class_decl,
|
|
|
class_scope.AddParent(scope_info.innermost_scope);
|
|
|
|
|
|
if (class_decl->extensibility() != ClassExtensibility::None) {
|
|
|
- return CompilationError(class_decl->source_loc())
|
|
|
+ return ProgramError(class_decl->source_loc())
|
|
|
<< "Class prefixes `base` and `abstract` are not supported yet";
|
|
|
}
|
|
|
if (class_decl->extends()) {
|
|
|
- return CompilationError(class_decl->source_loc())
|
|
|
+ return ProgramError(class_decl->source_loc())
|
|
|
<< "Class extension with `extends` is not supported yet";
|
|
|
}
|
|
|
|
|
|
@@ -3693,7 +3688,7 @@ auto TypeChecker::CheckImplIsDeducible(
|
|
|
impl_scope));
|
|
|
for (auto* expected_deduced : deduced_bindings) {
|
|
|
if (!deduced_args.count(expected_deduced)) {
|
|
|
- return CompilationError(source_loc)
|
|
|
+ return ProgramError(source_loc)
|
|
|
<< "parameter `" << *expected_deduced
|
|
|
<< "` is not deducible from `impl " << *impl_type << " as "
|
|
|
<< *impl_iface << "`";
|
|
|
@@ -3735,7 +3730,7 @@ auto TypeChecker::CheckImplIsComplete(Nonnull<const InterfaceType*> iface_type,
|
|
|
};
|
|
|
impl_decl->constraint_type()->VisitEqualValues(expected, visitor);
|
|
|
if (!found_any) {
|
|
|
- return CompilationError(impl_decl->source_loc())
|
|
|
+ return ProgramError(impl_decl->source_loc())
|
|
|
<< "implementation missing " << *expected;
|
|
|
} else if (!found_value) {
|
|
|
// TODO: It's not clear what the right rule is here. Clearly
|
|
|
@@ -3743,11 +3738,11 @@ auto TypeChecker::CheckImplIsComplete(Nonnull<const InterfaceType*> iface_type,
|
|
|
// ... is insufficient to establish a value for either X or Y.
|
|
|
// But perhaps we can allow
|
|
|
// impl forall [T:! HasX] T as HasY where .Y == .X {}
|
|
|
- return CompilationError(impl_decl->source_loc())
|
|
|
+ return ProgramError(impl_decl->source_loc())
|
|
|
<< "implementation doesn't provide a concrete value for "
|
|
|
<< *expected;
|
|
|
} else if (second_value) {
|
|
|
- return CompilationError(impl_decl->source_loc())
|
|
|
+ return ProgramError(impl_decl->source_loc())
|
|
|
<< "implementation provides multiple values for " << *expected
|
|
|
<< ": " << **found_value << " and " << **second_value;
|
|
|
}
|
|
|
@@ -3759,7 +3754,7 @@ auto TypeChecker::CheckImplIsComplete(Nonnull<const InterfaceType*> iface_type,
|
|
|
std::optional<Nonnull<const Declaration*>> mem =
|
|
|
FindMember(*mem_name, impl_decl->members());
|
|
|
if (!mem.has_value()) {
|
|
|
- return CompilationError(impl_decl->source_loc())
|
|
|
+ return ProgramError(impl_decl->source_loc())
|
|
|
<< "implementation missing " << *mem_name;
|
|
|
}
|
|
|
|
|
|
@@ -3823,7 +3818,7 @@ auto TypeChecker::CheckAndAddImplBindings(
|
|
|
witness, *this);
|
|
|
} else {
|
|
|
// TODO: Add support for implementing `adapter`s.
|
|
|
- return CompilationError(impl_decl->source_loc())
|
|
|
+ return ProgramError(impl_decl->source_loc())
|
|
|
<< "cannot implement a constraint whose lookup context includes "
|
|
|
<< *lookup.context;
|
|
|
}
|
|
|
@@ -3870,7 +3865,7 @@ auto TypeChecker::DeclareImplDeclaration(Nonnull<ImplDeclaration*> impl_decl,
|
|
|
impl_decl->interface().source_loc(), iface_type);
|
|
|
}
|
|
|
if (!isa<ConstraintType>(constraint_type)) {
|
|
|
- return CompilationError(impl_decl->interface().source_loc())
|
|
|
+ return ProgramError(impl_decl->interface().source_loc())
|
|
|
<< "expected constraint after `as`, found value of type "
|
|
|
<< *constraint_type;
|
|
|
}
|
|
|
@@ -4084,7 +4079,7 @@ auto TypeChecker::DeclareAliasDeclaration(Nonnull<AliasDeclaration*> alias,
|
|
|
TypeCheckExp(&alias->target(), *scope_info.innermost_scope));
|
|
|
|
|
|
if (!IsValidTypeForAliasTarget(&alias->target().static_type())) {
|
|
|
- return CompilationError(alias->source_loc())
|
|
|
+ return ProgramError(alias->source_loc())
|
|
|
<< "invalid target for alias declaration";
|
|
|
}
|
|
|
|
|
|
@@ -4164,7 +4159,7 @@ auto TypeChecker::TypeCheckDeclaration(
|
|
|
dyn_cast<ExpressionPattern>(&var.binding().type());
|
|
|
if (binding_type == nullptr) {
|
|
|
// TODO: consider adding support for `auto`
|
|
|
- return CompilationError(var.source_loc())
|
|
|
+ return ProgramError(var.source_loc())
|
|
|
<< "Type of a top-level variable must be an expression.";
|
|
|
}
|
|
|
if (var.has_initializer()) {
|
|
|
@@ -4243,7 +4238,7 @@ auto TypeChecker::DeclareDeclaration(Nonnull<Declaration*> d,
|
|
|
// Associate the variable name with it's declared type in the
|
|
|
// compile-time symbol table.
|
|
|
if (!llvm::isa<ExpressionPattern>(var.binding().type())) {
|
|
|
- return CompilationError(var.binding().type().source_loc())
|
|
|
+ return ProgramError(var.binding().type().source_loc())
|
|
|
<< "Expected expression for variable type";
|
|
|
}
|
|
|
Expression& type =
|
|
|
@@ -4349,12 +4344,12 @@ auto TypeChecker::CollectMember(Nonnull<const Declaration*> enclosing_decl,
|
|
|
auto [it, inserted] = encl_members.insert({member_name.value(), member_decl});
|
|
|
if (!inserted) {
|
|
|
if (member_decl == it->second) {
|
|
|
- return CompilationError(enclosing_decl_loc)
|
|
|
+ return ProgramError(enclosing_decl_loc)
|
|
|
<< "Member named " << member_name.value() << " (declared at "
|
|
|
<< member_decl->source_loc() << ")"
|
|
|
<< " is being mixed multiple times into " << enclosing_decl_name;
|
|
|
} else {
|
|
|
- return CompilationError(enclosing_decl_loc)
|
|
|
+ return ProgramError(enclosing_decl_loc)
|
|
|
<< "Member named " << member_name.value() << " (declared at "
|
|
|
<< member_decl->source_loc() << ") cannot be mixed into "
|
|
|
<< enclosing_decl_name
|