gccrs: New Error Code Framework

Updated ErrorCode struct to enum class to enforce proper
error codes, similiar to rustc. For converting the enum
to the respective error code, I used a map and updated
make_description & make_url function accordingly and
also removes the memory leak from the previous frame-
work. Also, added macro to safely convert the enum
number to string.

gcc/rust/ChangeLog:

	* backend/rust-compile-intrinsic.cc (Intrinsics::compile):
	Formatted according to enum class.
	* checks/errors/rust-feature-gate.cc (FeatureGate::gate): likewise.
	* checks/errors/rust-unsafe-checker.cc (check_unsafe_call): likewise.
	* hir/rust-ast-lower-base.cc (struct_field_name_exists): likewise.
	* resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): likewise.
	* resolve/rust-ast-resolve-path.cc (ResolvePath::resolve_path):
	likewise.
	* resolve/rust-ast-resolve-pattern.cc (PatternDeclaration::go): likewise.
	(PatternDeclaration::add_new_binding): likewise.
	* resolve/rust-ast-resolve-type.cc (ResolveRelativeTypePath::go): likewise.
	* resolve/rust-ast-verify-assignee.h: likewise.
	* rust-diagnostics.cc: updated make_desc & url function for enum class.
	* rust-diagnostics.h (struct ErrorCode): removed struct to switch to enum.
	(enum class): Switched from errorcode struct to enum class.
	(XSTR): Macro for converting enum to string.
	(STR): macro Used by XSTR for converting to string.
	(ERROR_CODE): macro used by map for check.
	(TABLE_TO_MAP): macro used by map for check
	* typecheck/rust-casts.cc (TypeCastRules::emit_cast_error):
	Formatted according to enum class.
	* typecheck/rust-hir-path-probe.h: likewise.
	* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): likewise.
	* typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelExternItem::visit):
	likewise.
	(TypeCheckImplItemWithTrait::visit): likewise.
	* typecheck/rust-hir-type-check-item.cc: likewise.
	* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): likewise.
	(emit_invalid_field_error): likewise.
	* typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::resolve): likewise.
	* typecheck/rust-tyty-call.cc (emit_unexpected_argument_error): likewise.
	(TypeCheckCallExpr::visit): likewise.
	* typecheck/rust-tyty-subst.cc (SubstitutionRef::get_mappings_from_generic_args):
	likewise.
	* typecheck/rust-tyty.cc (BaseType::bounds_compatible): likewise.

Signed-off-by: Muhammad Mahad <mahadtxt@gmail.com>
This commit is contained in:
Muhammad Mahad 2023-07-27 21:36:55 +05:00 committed by Arthur Cohen
parent ce7f0df47e
commit 55f8b63ab3
21 changed files with 1068 additions and 42 deletions

View file

@ -228,7 +228,7 @@ Intrinsics::compile (TyTy::FnType *fntype)
return it->second (ctx, fntype);
location_t locus = ctx->get_mappings ()->lookup_location (fntype->get_ref ());
rust_error_at (locus, ErrorCode ("E0093"),
rust_error_at (locus, ErrorCode::E0093,
"unrecognized intrinsic function: %<%s%>",
fntype->get_identifier ().c_str ());

View file

@ -79,7 +79,7 @@ FeatureGate::gate (Feature::Name name, Location loc,
"<https://github.com/rust-lang/rust/issues/%u> for more "
"information. add `#![feature(%s)]` to the crate attributes to "
"enable.";
rust_error_at (loc, ErrorCode ("E0658"), fmt_str, error_msg.c_str (),
rust_error_at (loc, ErrorCode::E0658, fmt_str, error_msg.c_str (),
issue, issue, feature.as_string ().c_str ());
}
else

View file

@ -86,7 +86,7 @@ static void
check_unsafe_call (HIR::Function *fn, location_t locus, const std::string &kind)
{
if (fn->get_qualifiers ().is_unsafe ())
rust_error_at (locus, ErrorCode ("E0133"),
rust_error_at (locus, ErrorCode::E0133,
"call to unsafe %s requires unsafe function or block",
kind.c_str ());
}

View file

@ -681,8 +681,7 @@ struct_field_name_exists (std::vector<HIR::StructField> &fields,
{
rich_location r (line_table, new_field.get_locus ());
r.add_range (field.get_locus ());
rust_error_at (r, ErrorCode ("E0124"),
"field %qs is already declared",
rust_error_at (r, ErrorCode::E0124, "field %qs is already declared",
field.get_field_name ().as_string ().c_str ());
return true;
}

View file

@ -173,7 +173,7 @@ ResolveExpr::visit (AST::IdentifierExpr &expr)
}
else
{
rust_error_at (expr.get_locus (), ErrorCode ("E0425"),
rust_error_at (expr.get_locus (), ErrorCode::E0425,
"cannot find value %qs in this scope",
expr.as_string ().c_str ());
}

View file

@ -62,7 +62,7 @@ ResolvePath::resolve_path (AST::PathInExpression *expr)
bool in_middle_of_path = i > 0;
if (in_middle_of_path && segment.is_lower_self_seg ())
{
rust_error_at (segment.get_locus (), ErrorCode ("E0433"),
rust_error_at (segment.get_locus (), ErrorCode::E0433,
"failed to resolve: %<%s%> in paths can only be used "
"in start position",
segment.as_string ().c_str ());
@ -206,7 +206,7 @@ ResolvePath::resolve_path (AST::PathInExpression *expr)
}
else if (is_first_segment)
{
rust_error_at (segment.get_locus (), ErrorCode ("E0433"),
rust_error_at (segment.get_locus (), ErrorCode::E0433,
"Cannot find path %<%s%> in this scope",
segment.as_string ().c_str ());
return UNKNOWN_NODEID;

View file

@ -42,7 +42,7 @@ PatternDeclaration::go (AST::Pattern *pattern, Rib::ItemType type,
auto ident = map_entry.first; // key
auto info = map_entry.second; // value
rust_error_at (info.get_locus (), ErrorCode ("E0408"),
rust_error_at (info.get_locus (), ErrorCode::E0408,
"variable '%s' is not bound in all patterns",
ident.as_string ().c_str ());
}
@ -53,7 +53,7 @@ PatternDeclaration::go (AST::Pattern *pattern, Rib::ItemType type,
auto info = map_entry.second; // value
rust_error_at (
info.get_locus (), ErrorCode ("E0409"),
info.get_locus (), ErrorCode::E0409,
"variable '%s' is bound inconsistently across pattern alternatives",
ident.as_string ().c_str ());
}
@ -278,7 +278,7 @@ PatternDeclaration::add_new_binding (Identifier ident, NodeId node_id,
{
if (type == Rib::ItemType::Param)
{
rust_error_at (info.get_locus (), ErrorCode ("E0415"),
rust_error_at (info.get_locus (), ErrorCode::E0415,
"identifier '%s' is bound more than once in the "
"same parameter list",
ident.as_string ().c_str ());
@ -286,7 +286,7 @@ PatternDeclaration::add_new_binding (Identifier ident, NodeId node_id,
else
{
rust_error_at (
info.get_locus (), ErrorCode ("E0416"),
info.get_locus (), ErrorCode::E0416,
"identifier '%s' is bound more than once in the same pattern",
ident.as_string ().c_str ());
}

View file

@ -98,7 +98,7 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
bool in_middle_of_path = i > 0;
if (in_middle_of_path && segment->is_lower_self_seg ())
{
rust_error_at (segment->get_locus (), ErrorCode ("E0433"),
rust_error_at (segment->get_locus (), ErrorCode::E0433,
"failed to resolve: %<%s%> in paths can only be used "
"in start position",
segment->as_string ().c_str ());

View file

@ -35,7 +35,7 @@ public:
VerifyAsignee checker;
assignee->accept_vis (checker);
if (!checker.ok)
rust_error_at (assignee->get_locus (), ErrorCode ("E0070"),
rust_error_at (assignee->get_locus (), ErrorCode::E0070,
"invalid left-hand side of assignment");
return checker.ok;
}

View file

@ -199,13 +199,13 @@ public:
char *make_description () const final override
{
return xstrdup (m_code.m_str);
return xstrdup (error_code_strings.at (m_code));
}
char *make_url () const final override
{
return concat ("https://doc.rust-lang.org/error-index.html#", m_code.m_str,
NULL);
return concat ("https://doc.rust-lang.org/error-index.html#",
error_code_strings.at (m_code), NULL);
}
private:

File diff suppressed because it is too large Load diff

View file

@ -304,7 +304,7 @@ TypeCastRules::emit_cast_error () const
rich_location r (line_table, locus);
r.add_range (from.get_locus ());
r.add_range (to.get_locus ());
rust_error_at (r, ErrorCode ("E0054"), "invalid cast %<%s%> to %<%s%>",
rust_error_at (r, ErrorCode::E0054, "invalid cast %<%s%> to %<%s%>",
from.get_ty ()->get_name ().c_str (),
to.get_ty ()->get_name ().c_str ());
}

View file

@ -164,7 +164,7 @@ public:
for (auto &c : candidates)
r.add_range (c.locus);
rust_error_at (r, ErrorCode ("E0034"),
rust_error_at (r, ErrorCode::E0034,
"multiple applicable items in scope for: %s",
query.as_string ().c_str ());
}

View file

@ -870,7 +870,7 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
rich_location r (line_table, expr.get_locus ());
r.add_range (expr.get_array_expr ()->get_locus ());
r.add_range (expr.get_index_expr ()->get_locus ());
rust_error_at (r, ErrorCode ("E0277"),
rust_error_at (r, ErrorCode::E0277,
"the type %<%s%> cannot be indexed by %<%s%>",
array_expr_ty->get_name ().c_str (),
index_expr_ty->get_name ().c_str ());
@ -1277,7 +1277,7 @@ TypeCheckExpr::visit (HIR::BreakExpr &expr)
{
if (!context->have_loop_context ())
{
rust_error_at (expr.get_locus (), ErrorCode ("E0268"),
rust_error_at (expr.get_locus (), ErrorCode::E0268,
"%<break%> outside of a loop or labeled block");
return;
}
@ -1312,7 +1312,7 @@ TypeCheckExpr::visit (HIR::ContinueExpr &expr)
{
if (!context->have_loop_context ())
{
rust_error_at (expr.get_locus (), ErrorCode ("E0268"),
rust_error_at (expr.get_locus (), ErrorCode::E0268,
"%<continue%> outside of a loop");
return;
}

View file

@ -143,7 +143,7 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
if (parent.get_abi () != Rust::ABI::C)
{
rust_error_at (
function.get_locus (), ErrorCode ("E0045"),
function.get_locus (), ErrorCode::E0045,
"C-variadic function must have C or cdecl calling convention");
}
}
@ -402,7 +402,7 @@ TypeCheckImplItemWithTrait::visit (HIR::ConstantItem &constant)
{
rich_location r (line_table, constant.get_locus ());
r.add_range (trait_reference.get_locus ());
rust_error_at (r, ErrorCode ("E0323"),
rust_error_at (r, ErrorCode::E0323,
"item %qs is an associated const, which does not match "
"its trait %qs",
constant.get_identifier ().as_string ().c_str (),
@ -539,7 +539,7 @@ TypeCheckImplItemWithTrait::visit (HIR::Function &function)
rich_location r (line_table, function.get_locus ());
r.add_range (resolved_trait_item.get_locus ());
rust_error_at (r, ErrorCode ("E0053"),
rust_error_at (r, ErrorCode::E0053,
"method %<%s%> has an incompatible type for trait %<%s%>",
function.get_function_name ().as_string ().c_str (),
trait_reference.get_name ().c_str ());

View file

@ -659,7 +659,7 @@ TypeCheckItem::validate_trait_impl_block (
r.add_range (missing_trait_item.get_locus ());
}
rust_error_at (r, ErrorCode ("E0046"),
rust_error_at (r, ErrorCode::E0046,
"missing %s in implementation of trait %<%s%>",
missing_items_buf.c_str (),
trait_reference->get_name ().c_str ());

View file

@ -112,7 +112,7 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
if (items_no_range.get_patterns ().size () != variant->num_fields ())
{
rust_error_at (
pattern.get_locus (), ErrorCode ("E0023"),
pattern.get_locus (), ErrorCode::E0023,
"this pattern has %lu fields but the corresponding "
"tuple variant has %lu field",
(unsigned long) items_no_range.get_patterns ().size (),
@ -143,7 +143,7 @@ void
emit_invalid_field_error (Location loc, Rust::TyTy::VariantDef *variant,
const std::string &name)
{
rust_error_at (loc, ErrorCode ("E0026"),
rust_error_at (loc, ErrorCode::E0026,
"variant %s does not have a field named %s",
variant->get_identifier ().c_str (), name.c_str ());
}
@ -268,7 +268,7 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
i++;
}
rust_error_at (pattern.get_locus (), ErrorCode ("E0027"),
rust_error_at (pattern.get_locus (), ErrorCode::E0027,
"pattern does not mention fields %s",
missing_fields_str.c_str ());
}

View file

@ -149,7 +149,7 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr)
}
else if (!struct_expr.has_struct_base ())
{
rust_error_at (struct_expr.get_locus (), ErrorCode ("E0063"),
rust_error_at (struct_expr.get_locus (), ErrorCode::E0063,
"constructor is missing fields");
return;
}

View file

@ -48,7 +48,7 @@ emit_unexpected_argument_error (Location loc,
{
err_msg += " but %lu arguments were supplied";
}
rust_error_at (loc, ErrorCode ("E0061"), err_msg.c_str (), expected_arg_count,
rust_error_at (loc, ErrorCode::E0061, err_msg.c_str (), expected_arg_count,
unexpected_arg_count);
}
@ -59,7 +59,7 @@ TypeCheckCallExpr::visit (ADTType &type)
if (variant.get_variant_type () != TyTy::VariantDef::VariantType::TUPLE)
{
rust_error_at (
call.get_locus (), ErrorCode ("E0423"),
call.get_locus (), ErrorCode::E0423,
"expected function, tuple struct or tuple variant, found struct %<%s%>",
type.get_name ().c_str ());
return;

View file

@ -606,7 +606,7 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args)
for (auto &binding : args.get_binding_args ())
r.add_range (binding.get_locus ());
rust_error_at (r, ErrorCode ("E0229"),
rust_error_at (r, ErrorCode::E0229,
"associated type bindings are not allowed here");
return SubstitutionArgumentMappings::error ();
}

View file

@ -397,7 +397,7 @@ BaseType::bounds_compatible (const BaseType &other, location_t locus,
if (emit_error)
{
rust_error_at (r, ErrorCode ("E0277"),
rust_error_at (r, ErrorCode::E0277,
"bounds not satisfied for %s %<%s%> is not satisfied",
other.get_name ().c_str (), missing_preds.c_str ());
// rust_assert (!emit_error);