aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-04-10 14:46:37 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-04-12 22:39:45 +0100
commitc3499198a97d2421990599c884a75ccfc775e122 (patch)
treea72c2bb9693ea8158f10800d9fb8b4dd83f42ece
parentca8744db3e56bfcf0cf3f0e2a0bf76450aef9438 (diff)
downloadgcc-c3499198a97d2421990599c884a75ccfc775e122.zip
gcc-c3499198a97d2421990599c884a75ccfc775e122.tar.gz
gcc-c3499198a97d2421990599c884a75ccfc775e122.tar.bz2
Seperate look for undetermined types post type resolution
When we do full PathInExpression resolution we can end up with orphaned Inference Variables which never get unified with real concrete types. This is to be expected. What we really care about are that all name declarations are fully typed before we move into the next pass.
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc54
-rw-r--r--gcc/rust/typecheck/rust-tyty.h19
2 files changed, 63 insertions, 10 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 8b2f657..681fb24 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -44,9 +44,11 @@ TypeResolution::Resolve (HIR::Crate &crate)
if (saw_errors ())
return;
+ auto resolver = Resolver::Resolver::get ();
auto mappings = Analysis::Mappings::get ();
auto context = TypeCheckContext::get ();
+ // default inference variables if possible
context->iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
if (ty->get_kind () == TyTy::TypeKind::ERROR)
{
@@ -61,19 +63,51 @@ TypeResolution::Resolve (HIR::Crate &crate)
TyTy::InferType *infer_var = (TyTy::InferType *) ty;
TyTy::BaseType *default_type;
bool ok = infer_var->default_type (&default_type);
- if (!ok)
+ if (ok)
{
- rust_error_at (mappings->lookup_location (id),
- "unable to determine type: please give this a type: %u",
- id);
- return true;
+ auto result = ty->unify (default_type);
+ result->set_ref (id);
+ context->insert_type (
+ Analysis::NodeMapping (mappings->get_current_crate (), 0, id,
+ UNKNOWN_LOCAL_DEFID),
+ result);
}
- auto result = ty->unify (default_type);
- result->set_ref (id);
- context->insert_type (Analysis::NodeMapping (mappings->get_current_crate (),
- 0, id, UNKNOWN_LOCAL_DEFID),
- result);
+ return true;
+ });
+
+ // scan the ribs to ensure the decls are all setup correctly
+ resolver->iterate_name_ribs ([&] (Rib *r) -> bool {
+ r->iterate_decls ([&] (NodeId decl_node_id, Location locus) -> bool {
+ Definition def;
+ if (!resolver->lookup_definition (decl_node_id, &def))
+ {
+ rust_error_at (locus, "failed to lookup decl def");
+ return true;
+ }
+
+ HirId hir_node = UNKNOWN_HIRID;
+ if (!mappings->lookup_node_to_hir (mappings->get_current_crate (),
+ def.parent, &hir_node))
+ {
+ rust_error_at (locus, "failed to lookup type hir node id");
+ return true;
+ }
+ // lookup the ty
+ TyTy::BaseType *ty = nullptr;
+ bool ok = context->lookup_type (hir_node, &ty);
+ if (!ok)
+ {
+ rust_error_at (locus, "failed to lookup type for decl node_id: %u",
+ decl_node_id);
+ return true;
+ }
+
+ if (!ty->is_concrete ())
+ rust_error_at (locus, "unable to determine type");
+
+ return true;
+ });
return true;
});
}
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 7b4197f..9cf75fa 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -91,6 +91,8 @@ public:
virtual bool is_unit () const { return false; }
+ virtual bool is_concrete () const { return true; }
+
TypeKind get_kind () const { return kind; }
/* Returns a pointer to a clone of this. The caller is responsible for
@@ -194,6 +196,8 @@ public:
bool default_type (BaseType **type) const;
+ bool is_concrete () const final override { return false; }
+
private:
InferTypeKind infer_kind;
};
@@ -321,6 +325,16 @@ public:
BaseType *clone () final override;
+ bool is_concrete () const override final
+ {
+ for (size_t i = 0; i < num_fields (); i++)
+ {
+ if (!get_field (i)->is_concrete ())
+ return false;
+ }
+ return true;
+ }
+
void iterate_fields (std::function<bool (BaseType *)> cb) const
{
for (size_t i = 0; i < num_fields (); i++)
@@ -824,6 +838,11 @@ public:
BaseType *clone () final override;
+ bool is_concrete () const final override
+ {
+ return get_element_type ()->is_concrete ();
+ }
+
private:
size_t capacity;
TyVar element_type;