From: Philip Herron <[email protected]>
The error handling here was done long ago when we didnt know how to do
any error handling very well. This removed bad fatal_errors and adds in
some nice rich_location error diagnostics instead.
Fixes Rust-GCC#3628
gcc/rust/ChangeLog:
* typecheck/rust-hir-type-check-struct-field.h: keep reference to
parent expression
* typecheck/rust-hir-type-check-struct.cc
(TypeCheckStructExpr::TypeCheckStructExpr):
update ctor
(TypeCheckStructExpr::resolve): remove bad rust_fatal_errors
(TypeCheckStructExpr::visit): cleanup errors
gcc/testsuite/ChangeLog:
* rust/compile/macros/mbe/macro-issue2983_2984.rs: cleanup error
diagnotics
* rust/compile/struct_init1.rs: likewise
* rust/compile/issue-3628.rs: New test.
Signed-off-by: Philip Herron <[email protected]>
---
.../rust-hir-type-check-struct-field.h | 3 ++
.../typecheck/rust-hir-type-check-struct.cc | 54 +++++++++----------
gcc/testsuite/rust/compile/issue-3628.rs | 10 ++++
.../macros/mbe/macro-issue2983_2984.rs | 5 +-
gcc/testsuite/rust/compile/struct_init1.rs | 6 +--
5 files changed, 45 insertions(+), 33 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/issue-3628.rs
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
b/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
index 800f7ca4390..7e3a57addec 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
@@ -60,6 +60,9 @@ private:
TyTy::BaseType *resolved_field_value_expr;
std::set<std::string> fields_assigned;
std::map<size_t, HIR::StructExprField *> adtFieldIndexToField;
+
+ // parent
+ HIR::Expr &parent;
};
} // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct.cc
b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
index 40c42b27980..df1636a584a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
@@ -28,7 +28,7 @@ TypeCheckStructExpr::TypeCheckStructExpr (HIR::Expr &e)
: TypeCheckBase (),
resolved (new TyTy::ErrorType (e.get_mappings ().get_hirid ())),
struct_path_resolved (nullptr),
- variant (&TyTy::VariantDef::get_error_node ())
+ variant (&TyTy::VariantDef::get_error_node ()), parent (e)
{}
TyTy::BaseType *
@@ -65,7 +65,7 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields
&struct_expr)
if (base_unify->get_kind () != struct_path_ty->get_kind ())
{
- rust_fatal_error (
+ rust_error_at (
struct_expr.get_struct_base ().get_base ().get_locus (),
"incompatible types for base struct reference");
return;
@@ -82,7 +82,16 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields
&struct_expr)
bool ok = context->lookup_variant_definition (
struct_expr.get_struct_name ().get_mappings ().get_hirid (),
&variant_id);
- rust_assert (ok);
+ if (!ok)
+ {
+ rich_location r (line_table, struct_expr.get_locus ());
+ r.add_range (struct_expr.get_struct_name ().get_locus ());
+ rust_error_at (
+ struct_expr.get_struct_name ().get_locus (), ErrorCode::E0574,
+ "expected a struct, variant or union type, found enum %qs",
+ struct_path_resolved->get_name ().c_str ());
+ return;
+ }
ok = struct_path_resolved->lookup_variant_by_id (variant_id, &variant);
rust_assert (ok);
@@ -118,29 +127,14 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields
&struct_expr)
break;
}
- if (!ok)
- {
- return;
- }
-
- if (resolved_field_value_expr == nullptr)
- {
- rust_fatal_error (field->get_locus (),
- "failed to resolve type for field");
- ok = false;
- break;
- }
-
- context->insert_type (field->get_mappings (), resolved_field_value_expr);
+ if (ok)
+ context->insert_type (field->get_mappings (),
+ resolved_field_value_expr);
}
- // something failed setting up the fields
+ // something failed setting up the fields and error's emitted
if (!ok)
- {
- rust_error_at (struct_expr.get_locus (),
- "constructor type resolution failure");
- return;
- }
+ return;
// check the arguments are all assigned and fix up the ordering
std::vector<std::string> missing_field_names;
@@ -271,8 +265,11 @@ TypeCheckStructExpr::visit
(HIR::StructExprFieldIdentifierValue &field)
&field_index);
if (!ok)
{
- rust_error_at (field.get_locus (), "unknown field");
- return true;
+ rich_location r (line_table, parent.get_locus ());
+ r.add_range (field.get_locus ());
+ rust_error_at (r, ErrorCode::E0560, "unknown field %qs",
+ field.field_name.as_string ().c_str ());
+ return false;
}
auto it = adtFieldIndexToField.find (field_index);
@@ -317,8 +314,11 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIndexValue
&field)
bool ok = variant->lookup_field (field_name, &field_type, &field_index);
if (!ok)
{
- rust_error_at (field.get_locus (), "unknown field");
- return true;
+ rich_location r (line_table, parent.get_locus ());
+ r.add_range (field.get_locus ());
+ rust_error_at (r, ErrorCode::E0560, "unknown field %qs",
+ field_name.c_str ());
+ return false;
}
auto it = adtFieldIndexToField.find (field_index);
diff --git a/gcc/testsuite/rust/compile/issue-3628.rs
b/gcc/testsuite/rust/compile/issue-3628.rs
new file mode 100644
index 00000000000..5f5978918e4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3628.rs
@@ -0,0 +1,10 @@
+pub enum Enum {
+ Variant1(isize),
+}
+
+impl Enum {
+ fn static_meth_enum() -> Enum {
+ Enum { x: 1 }
+ // { dg-error "expected a struct, variant or union type, found enum
.Enum. .E0574." "" { target *-*-* } .-1 }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue2983_2984.rs
b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2983_2984.rs
index 637d5728c50..eeae6ebb9a5 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro-issue2983_2984.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2983_2984.rs
@@ -18,10 +18,9 @@ fn main() {
// Error
let _ = ReadDir {
+ // { dg-error "unknown field .end_of_stream_but_different. .E0560." ""
{ target *-*-* } .-1 }
inner: 14,
end_of_stream: false,
- end_of_stream_but_different: false, // { dg-error "failed to resolve
type for field" }
- // { dg-error "unknown field" "" { target *-*-* } .-1 }
- // { dg-prune-output "compilation terminated" }
+ end_of_stream_but_different: false,
};
}
diff --git a/gcc/testsuite/rust/compile/struct_init1.rs
b/gcc/testsuite/rust/compile/struct_init1.rs
index 1875fb4f33e..38f6f3802a9 100644
--- a/gcc/testsuite/rust/compile/struct_init1.rs
+++ b/gcc/testsuite/rust/compile/struct_init1.rs
@@ -4,7 +4,7 @@ struct Foo {
}
fn main() {
- let a = Foo { 0: 10.0, 1: 20.0 }; // { dg-error "failed to resolve type
for field" }
- // { dg-error "unknown field" "" { target *-*-* } .-1 }
- // { dg-prune-output "compilation terminated" }
+ let a = Foo { 0: 10.0, 1: 20.0 };
+ // { dg-error "unknown field .0. .E0560." "" { target *-*-* } .-1 }
+ // { dg-error "unknown field .1. .E0560." "" { target *-*-* } .-2 }
}
--
2.49.0