From 0c5a6af749de89d5e21a525e74b94b01b3f3b35f Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Sat, 10 Apr 2021 15:16:50 +0100 Subject: Unify ADTRules needs to check identifier When unifying algebraic data types we must check the identifiers match as well as everything else. We also should not be relying on nullptr checks for resolution failures but use TyTy::Error nodes. --- gcc/rust/typecheck/rust-tyty-rules.h | 40 +++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'gcc') diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h index 0fb04c5..c23cbc1 100644 --- a/gcc/rust/typecheck/rust-tyty-rules.h +++ b/gcc/rust/typecheck/rust-tyty-rules.h @@ -67,8 +67,8 @@ public: } other->accept_vis (*this); - if (resolved == nullptr) - return nullptr; + if (resolved->get_kind () == TyTy::TypeKind::ERROR) + return resolved; resolved->append_reference (get_base ()->get_ref ()); resolved->append_reference (other->get_ref ()); @@ -81,7 +81,7 @@ public: bool result_is_infer_var = resolved->get_kind () == TyTy::TypeKind::INFER; bool results_is_non_general_infer_var = (result_is_infer_var - && ((InferType *) resolved)->get_infer_kind () + && (static_cast (resolved))->get_infer_kind () != TyTy::InferType::GENERAL); if (result_resolved || results_is_non_general_infer_var) { @@ -229,7 +229,7 @@ public: virtual void visit (ParamType &type) override { Location ref_locus = mappings->lookup_location (type.get_ref ()); - rust_error_at (ref_locus, "expected [%s] got [ParamTy <%s>]", + rust_error_at (ref_locus, "expected [%s] got [%s]", get_base ()->as_string ().c_str (), type.as_string ().c_str ()); } @@ -829,6 +829,12 @@ public: void visit (ADTType &type) override { + if (base->get_identifier ().compare (type.get_identifier ()) != 0) + { + BaseRules::visit (type); + return; + } + if (base->num_fields () != type.num_fields ()) { BaseRules::visit (type); @@ -844,11 +850,8 @@ public: TyTy::BaseType *other_field_ty = other_field->get_field_type (); BaseType *unified_ty = this_field_ty->unify (other_field_ty); - if (unified_ty == nullptr) - { - BaseRules::visit (type); - return; - } + if (unified_ty->get_kind () == TyTy::TypeKind::ERROR) + return; } resolved = type.clone (); @@ -882,11 +885,8 @@ public: BaseType *fo = type.get_field (i); BaseType *unified_ty = bo->unify (fo); - if (unified_ty == nullptr) - { - BaseRules::visit (type); - return; - } + if (unified_ty->get_kind () == TyTy::TypeKind::ERROR) + return; fields.push_back (TyVar (unified_ty->get_ref ())); } @@ -1034,6 +1034,7 @@ public: { if (base->get_ref () == base->get_ty_ref ()) return BaseRules::unify (other); + auto context = Resolver::TypeCheckContext::get (); BaseType *lookup = nullptr; bool ok = context->lookup_type (base->get_ty_ref (), &lookup); @@ -1053,6 +1054,17 @@ public: resolved = type.clone (); } + void visit (InferType &type) override + { + if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL) + { + BaseRules::visit (type); + return; + } + + resolved = base->clone (); + } + private: BaseType *get_base () override { return base; } -- cgit v1.1