diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-01-18 22:57:46 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-01-19 12:53:02 +0000 |
commit | 89631998d2ffda0c0c05066c148c6fc19398da5c (patch) | |
tree | 2427840c4b76b2b295687f080133508f607e03a5 | |
parent | 3713577c36eeba454e8bd3aef6bfce5ee6683c2b (diff) | |
download | gcc-89631998d2ffda0c0c05066c148c6fc19398da5c.zip gcc-89631998d2ffda0c0c05066c148c6fc19398da5c.tar.gz gcc-89631998d2ffda0c0c05066c148c6fc19398da5c.tar.bz2 |
Delcare first case for ADT types field access fail to type resolve.
The type resolver must ensure LHS for assignments where the LHS was
infered to be ? and the node mappings have a definition ID we know
the declaration id and can reassign the TyTy so further references know
its type.
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 38 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/type_infer5.rs | 11 |
2 files changed, 46 insertions, 3 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index a6cf286..a49dc70 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -137,9 +137,41 @@ public: auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ()); infered = lhs->combine (rhs); - // need to overrite the lhs type with this combination - context->insert_type (expr.get_lhs ()->get_mappings ().get_hirid (), - infered); + + // in the case of declare first for an ADT Type: + // + // let a; + // a = Foo{..} + // let b = a.field; + // + // The lhs will have a TyTy of INFER and so when the declaration is + // referenced it will still have an unknown type so we will fail to resolve + // FieldAccessExpr + if (lhs->get_kind () == TyTy::TypeKind::INFER) + { + NodeId ast_node_id = expr.get_lhs ()->get_mappings ().get_nodeid (); + NodeId ref_node_id; + if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id)) + return; + + Definition def; + if (!resolver->lookup_definition (ref_node_id, &def)) + { + rust_error_at (expr.get_locus (), + "assignment infer - unknown reference"); + return; + } + + HirId ref; + if (!mappings->lookup_node_to_hir ( + expr.get_mappings ().get_crate_num (), def.parent, &ref)) + { + rust_error_at (expr.get_locus (), + "assignment infer - reverse lookup failure"); + return; + } + context->insert_type (ref, infered); + } } void visit (HIR::IdentifierExpr &expr) diff --git a/gcc/testsuite/rust.test/compilable/type_infer5.rs b/gcc/testsuite/rust.test/compilable/type_infer5.rs new file mode 100644 index 0000000..65c7058 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/type_infer5.rs @@ -0,0 +1,11 @@ +struct Foo { + a: i32, + b: i32, +} + +fn main() { + let a; + a = Foo { a: 1, b: 2 }; + + let b = a.a; +} |