diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-04-10 14:46:37 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-04-12 22:39:45 +0100 |
commit | c3499198a97d2421990599c884a75ccfc775e122 (patch) | |
tree | a72c2bb9693ea8158f10800d9fb8b4dd83f42ece /gcc | |
parent | ca8744db3e56bfcf0cf3f0e2a0bf76450aef9438 (diff) | |
download | gcc-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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.cc | 54 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 19 |
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; |