From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by sourceware.org (Postfix) with ESMTPS id BB72D3939C25 for ; Tue, 31 Jan 2023 13:21:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BB72D3939C25 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-wm1-x329.google.com with SMTP id bg26so4479081wmb.0 for ; Tue, 31 Jan 2023 05:21:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=1bUr8MOaIoXlmGglG7xAt73Ust6Zb6rON/YQwfnjQlQ=; b=Xw9RbQDV16PAn1PYEO96g1JcPmVDeaPfudPWR4MqeznBICn1gOEsGjlPLGO1iztD31 3DBz65rAbLUggv3bFpNjXJFWqRJi4IrCQ57StFZc1rS3wc1SbynIZrhOFoRBsM1QLppW Pi4JsjuXuzDmy5qYU2Byd3BhQ/VO0lKDttmNW4kkDZmW10kRxaGIzq7+skCcz/rXhdIo zETyl/pS7taoDF8sLCL2TASsI4bbHqYL7/UA3gy4zyG+AVzxYUt8ODg4iHrsa6AihJqp W/8BrztS0RJ8QjNyHidDMlZOhuEKoLAQis9Y657wnOuKJrwosYuSIi1Gh7ujWUsCjoA3 tVig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=1bUr8MOaIoXlmGglG7xAt73Ust6Zb6rON/YQwfnjQlQ=; b=cplKEnoo+84tk6l3oLM1ZHRFWiGChAfBIL0u9GgdgIqm2EpdGsVRkYUekgrpPPkpOL yg9vq1IbtUkfyvpMdROFvqfxP2lPKLVol3NO6Di1mcGes0CiGLaVG0l9kunO1LNRiN+2 PmcsPrzau22LPpHmLcIu4/CKaArIfVcA3wJs3kjhSZjhoggiD05KfoJ+0HtYZc+gpJlX NnRuQGATiyC67Dx5/nCuehVzrmmiRrOUudc0iH1ciEdWNCuoTcghW51rFkWwocjVXRQe w/vgp6XC6MqTTiuPVv58Wte2prAxBNm0xxcoUFQH3HJL1Msj66ghTgbYpOhcYekfLwNW bC+g== X-Gm-Message-State: AO0yUKXJCxkLFvdCViddJrHjl/+pAm8JRA6EpRmALguB2gerhXsQL6RC QnZrku+wFCrVM9UR+LOXp6M+7frJfML1k7d8rw== X-Google-Smtp-Source: AK7set8qdu7Rp6o50zYILlyTx5MFCkpF7zEklIDgkf91bicKPqbjK3UauwPFIMtEhCaI9YWmYLrMPw== X-Received: by 2002:a05:600c:4fc6:b0:3dc:1f90:35b with SMTP id o6-20020a05600c4fc600b003dc1f90035bmr25378808wmq.34.1675171300947; Tue, 31 Jan 2023 05:21:40 -0800 (PST) Received: from platypus.lan ([2001:861:5e4c:3bb0:6424:328a:1734:3249]) by smtp.gmail.com with ESMTPSA id j39-20020a05600c48a700b003db12112fcfsm1715982wmp.4.2023.01.31.05.21.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Jan 2023 05:21:40 -0800 (PST) From: Arthur Cohen To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Philip Herron Subject: [COMMITTED] gccrs: Refactor unify to hit a unify_site Date: Tue, 31 Jan 2023 14:25:25 +0100 Message-Id: <20230131132525.662143-1-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-15.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Philip Herron This allows us to enforce better error handling on unify sites gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::unify_site): Add better unification function with debug calls. * typecheck/rust-autoderef.cc (AutoderefCycle::cycle): Add more debug calls and use new unify API. * typecheck/rust-coercion.cc (TypeCoercionRules::do_coercion): Likewise. (TypeCoercionRules::coerce_borrowed_pointer): Likewise. (TypeCoercionRules::select): Likewise. * typecheck/rust-hir-dot-operator.cc (MethodResolver::select): Likewise. * typecheck/rust-hir-trait-resolve.cc (TraitItemReference::resolve_item): Likewise. (TypeCheckBase::coercion_site): Likewise. (TypeCheckBase::cast_site): Likewise. * typecheck/rust-hir-type-check-base.h: Likewise. * typecheck/rust-hir-type-check-enumitem.cc (TypeCheckEnumItem::visit): Likewise. * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise. * typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelImplItem::visit): Likewise. (TypeCheckImplItem::visit): Likewise. * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): Likewise. * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): Likewise. * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): Likewise. * typecheck/rust-hir-type-check-stmt.cc (TypeCheckStmt::visit): Likewise. * typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::resolve): Likewise. * typecheck/rust-hir-type-check-toplevel.cc (TypeCheckTopLevel::visit): Likewise. * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): Likewise. * typecheck/rust-hir-type-check.cc (TypeResolution::Resolve): Likewise. * typecheck/rust-tyctx.cc (TypeCheckContext::peek_return_type): Likewise. * typecheck/rust-tyty-call.cc (TypeCheckMethodCallExpr::visit): Likewise. * typecheck/rust-tyty-cmp.h: Likewise. * typecheck/rust-tyty-rules.h: Likewise. * typecheck/rust-tyty.cc (BaseType::mappings_str): Likewise. (BaseType::debug): Print type name more clearly. (BaseType::debug_str): Add new function to print type pointer and name. (TupleType::get_name): Improve type name fetching function. (ReferenceType::get_name): Likewise. (PointerType::get_name): Likewise. * typecheck/rust-tyty.h: Refactor definitions outside of the header. gcc/testsuite/ChangeLog: * rust/compile/issue-1152.rs: Fix dejagnu assertion. * rust/compile/tuple1.rs: Likewise. * rust/compile/type-alias1.rs: Likewise. * rust/execute/torture/operator_overload_9.rs: Likewise. * rust/execute/torture/slice1.rs: Rework test to use new parsing capability and stick to the original implementation. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/rust/typecheck/rust-autoderef.cc | 15 +- gcc/rust/typecheck/rust-coercion.cc | 62 +++- gcc/rust/typecheck/rust-hir-dot-operator.cc | 15 + gcc/rust/typecheck/rust-hir-trait-resolve.cc | 24 +- .../typecheck/rust-hir-type-check-base.cc | 42 ++- gcc/rust/typecheck/rust-hir-type-check-base.h | 4 + .../typecheck/rust-hir-type-check-enumitem.cc | 6 +- .../typecheck/rust-hir-type-check-expr.cc | 170 ++++++++--- .../typecheck/rust-hir-type-check-implitem.cc | 17 +- .../typecheck/rust-hir-type-check-item.cc | 11 +- .../typecheck/rust-hir-type-check-path.cc | 5 +- .../typecheck/rust-hir-type-check-pattern.cc | 4 +- .../typecheck/rust-hir-type-check-stmt.cc | 15 +- .../typecheck/rust-hir-type-check-struct.cc | 12 +- .../typecheck/rust-hir-type-check-toplevel.cc | 15 +- .../typecheck/rust-hir-type-check-type.cc | 8 +- gcc/rust/typecheck/rust-hir-type-check.cc | 12 +- gcc/rust/typecheck/rust-tyctx.cc | 1 + gcc/rust/typecheck/rust-tyty-call.cc | 5 +- gcc/rust/typecheck/rust-tyty-cmp.h | 4 +- gcc/rust/typecheck/rust-tyty-rules.h | 264 ++---------------- gcc/rust/typecheck/rust-tyty.cc | 61 +++- gcc/rust/typecheck/rust-tyty.h | 36 +-- gcc/testsuite/rust/compile/issue-1152.rs | 2 - gcc/testsuite/rust/compile/tuple1.rs | 2 +- gcc/testsuite/rust/compile/type-alias1.rs | 2 +- .../execute/torture/operator_overload_9.rs | 2 +- gcc/testsuite/rust/execute/torture/slice1.rs | 7 +- 28 files changed, 460 insertions(+), 363 deletions(-) diff --git a/gcc/rust/typecheck/rust-autoderef.cc b/gcc/rust/typecheck/rust-autoderef.cc index 71d39cff3de..ca43f847e98 100644 --- a/gcc/rust/typecheck/rust-autoderef.cc +++ b/gcc/rust/typecheck/rust-autoderef.cc @@ -255,7 +255,12 @@ resolve_operator_overload_fn ( lookup = fn->infer_substitions (Location ()); rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF); fn = static_cast (lookup); - fn->get_self_type ()->unify (adjusted_self); + + Location unify_locus = mappings->lookup_location (ty->get_ref ()); + TypeCheckBase::unify_site ( + ty->get_ref (), TyTy::TyWithLocation (fn->get_self_type ()), + TyTy::TyWithLocation (adjusted_self), unify_locus); + lookup = fn; } } @@ -284,6 +289,7 @@ AutoderefCycle::cycle (const TyTy::BaseType *receiver) const TyTy::BaseType *r = receiver; while (true) { + rust_debug ("autoderef try 1: {%s}", r->debug_str ().c_str ()); if (try_autoderefed (r)) return true; @@ -292,12 +298,15 @@ AutoderefCycle::cycle (const TyTy::BaseType *receiver) return false; // try unsize + Adjustment unsize = Adjuster::try_unsize_type (r); if (!unsize.is_error ()) { adjustments.push_back (unsize); auto unsize_r = unsize.get_expected (); + rust_debug ("autoderef try unsize: {%s}", + unsize_r->debug_str ().c_str ()); if (try_autoderefed (unsize_r)) return true; @@ -311,6 +320,8 @@ AutoderefCycle::cycle (const TyTy::BaseType *receiver) auto deref_r = deref.get_expected (); adjustments.push_back (deref); + rust_debug ("autoderef try lang-item DEREF: {%s}", + deref_r->debug_str ().c_str ()); if (try_autoderefed (deref_r)) return true; @@ -324,6 +335,8 @@ AutoderefCycle::cycle (const TyTy::BaseType *receiver) auto deref_r = deref_mut.get_expected (); adjustments.push_back (deref_mut); + rust_debug ("autoderef try lang-item DEREF_MUT: {%s}", + deref_r->debug_str ().c_str ()); if (try_autoderefed (deref_r)) return true; diff --git a/gcc/rust/typecheck/rust-coercion.cc b/gcc/rust/typecheck/rust-coercion.cc index ceba6a843f9..fdf8eb95a33 100644 --- a/gcc/rust/typecheck/rust-coercion.cc +++ b/gcc/rust/typecheck/rust-coercion.cc @@ -16,6 +16,7 @@ // along with GCC; see the file COPYING3. If not see // . +#include "rust-hir-type-check-base.h" #include "rust-coercion.h" namespace Rust { @@ -53,6 +54,49 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver) // see: // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs + // handle never + // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L155 + if (receiver->get_kind () == TyTy::TypeKind::NEVER) + { + // Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound + // type variable, we want `?T` to fallback to `!` if not + // otherwise constrained. An example where this arises: + // + // let _: Option = Some({ return; }); + // + // here, we would coerce from `!` to `?T`. + if (expected->has_subsititions_defined () && !expected->is_concrete ()) + { + Location locus = mappings->lookup_location (receiver->get_ref ()); + TyTy::TyVar implicit_var + = TyTy::TyVar::get_implicit_infer_var (locus); + try_result = CoercionResult{{}, implicit_var.get_tyty ()}; + return true; + } + else + { + bool expected_is_infer_var + = expected->get_kind () == TyTy::TypeKind::INFER; + bool expected_is_general_infer_var + = expected_is_infer_var + && (static_cast (expected)->get_infer_kind () + == TyTy::InferType::InferTypeKind::GENERAL); + + // FIXME this 'expected_is_general_infer_var' case needs to eventually + // should go away see: compile/never_type_err1.rs + // + // I think we need inference obligations to say that yes we have a + // general inference variable but we add the oligation to the expected + // type that it could default to '!' + if (expected_is_general_infer_var) + try_result = CoercionResult{{}, receiver}; + else + try_result = CoercionResult{{}, expected->clone ()}; + + return true; + } + } + // unsize bool unsafe_error = false; CoercionResult unsize_coercion @@ -163,13 +207,17 @@ TypeCoercionRules::coerce_borrowed_pointer (TyTy::BaseType *receiver, switch (receiver->get_kind ()) { case TyTy::TypeKind::REF: { - TyTy::ReferenceType *ref + TyTy::ReferenceType *from = static_cast (receiver); - from_mutbl = ref->mutability (); + from_mutbl = from->mutability (); } break; default: { + // FIXME + // we might be able to replace this with a can_eq because we default + // back to a final unity anyway + rust_debug ("coerce_borrowed_pointer -- unify"); TyTy::BaseType *result = receiver->unify (expected); return CoercionResult{{}, result}; } @@ -183,7 +231,12 @@ TypeCoercionRules::coerce_borrowed_pointer (TyTy::BaseType *receiver, return TypeCoercionRules::CoercionResult::get_error (); } + rust_debug ("coerce_borrowed_pointer -- autoderef cycle"); AutoderefCycle::cycle (receiver); + rust_debug ("coerce_borrowed_pointer -- result: [%s] with adjustments: [%zu]", + try_result.is_error () ? "failed" : "matched", + try_result.adjustments.size ()); + return try_result; } @@ -310,7 +363,10 @@ TypeCoercionRules::coerce_unsized (TyTy::BaseType *source, bool TypeCoercionRules::select (const TyTy::BaseType &autoderefed) { - if (autoderefed.can_eq (expected, false)) + rust_debug ( + "autoderef type-coercion select autoderefed={%s} can_eq expected={%s}", + autoderefed.debug_str ().c_str (), expected->debug_str ().c_str ()); + if (expected->can_eq (&autoderefed, false)) { try_result = CoercionResult{adjustments, autoderefed.clone ()}; return true; diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc b/gcc/rust/typecheck/rust-hir-dot-operator.cc index 1cef7fe38a6..985e61b83f0 100644 --- a/gcc/rust/typecheck/rust-hir-dot-operator.cc +++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc @@ -171,12 +171,21 @@ MethodResolver::select (const TyTy::BaseType &receiver) TyTy::FnType *fntype; }; + rust_debug ("inherent_impl_fns found {%lu}, trait_fns found {%lu}, " + "predicate_items found {%lu}", + (unsigned long) inherent_impl_fns.size (), + (unsigned long) trait_fns.size (), + (unsigned long) predicate_items.size ()); + for (auto impl_item : inherent_impl_fns) { TyTy::FnType *fn = impl_item.ty; rust_assert (fn->is_method ()); TyTy::BaseType *fn_self = fn->get_self_type (); + rust_debug ("dot-operator impl_item fn_self={%s} can_eq receiver={%s}", + fn_self->debug_str ().c_str (), + receiver.debug_str ().c_str ()); if (fn_self->can_eq (&receiver, false)) { PathProbeCandidate::ImplItemCandidate c{impl_item.item, @@ -195,6 +204,9 @@ MethodResolver::select (const TyTy::BaseType &receiver) rust_assert (fn->is_method ()); TyTy::BaseType *fn_self = fn->get_self_type (); + rust_debug ("dot-operator trait_item fn_self={%s} can_eq receiver={%s}", + fn_self->debug_str ().c_str (), + receiver.debug_str ().c_str ()); if (fn_self->can_eq (&receiver, false)) { PathProbeCandidate::TraitItemCandidate c{trait_item.reference, @@ -214,6 +226,9 @@ MethodResolver::select (const TyTy::BaseType &receiver) rust_assert (fn->is_method ()); TyTy::BaseType *fn_self = fn->get_self_type (); + rust_debug ("dot-operator predicate fn_self={%s} can_eq receiver={%s}", + fn_self->debug_str ().c_str (), + receiver.debug_str ().c_str ()); if (fn_self->can_eq (&receiver, false)) { const TraitReference *trait_ref diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index 93cef97afd3..c14a6c3a9be 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc @@ -324,10 +324,18 @@ TraitItemReference::resolve_item (HIR::TraitItemFunc &func) auto block_expr_ty = TypeCheckExpr::Resolve (func.get_block_expr ().get ()); - context->pop_return_type (); + Location fn_return_locus + = func.get_decl ().has_return_type () + ? func.get_decl ().get_return_type ()->get_locus () + : func.get_locus (); + + TypeCheckBase::coercion_site (func.get_mappings ().get_hirid (), + TyTy::TyWithLocation (expected_ret_tyty, + fn_return_locus), + TyTy::TyWithLocation (block_expr_ty), + func.get_locus ()); - if (block_expr_ty->get_kind () != TyTy::NEVER) - expected_ret_tyty->unify (block_expr_ty); + context->pop_return_type (); } void @@ -457,7 +465,10 @@ AssociatedImplTrait::setup_associated_types ( // the type correctly as our receiver may be generic and we are inferring its // generic arguments and this Self might be the concrete version or vice // versa. - auto result = receiver->unify (impl_self_infer); + auto result = TypeCheckBase::unify_site ( + get_impl_block ()->get_mappings ().get_hirid (), + TyTy::TyWithLocation (receiver), TyTy::TyWithLocation (impl_self_infer), + impl_predicate.get_locus ()); rust_assert (result->get_kind () != TyTy::TypeKind::ERROR); // unify the bounds arguments @@ -479,7 +490,10 @@ AssociatedImplTrait::setup_associated_types ( TyTy::BaseType *a = impl_trait_predicate_args.at (i); TyTy::BaseType *b = hrtb_bound_arguments.at (i); - result = a->unify (b); + result + = TypeCheckBase::unify_site (a->get_ref (), TyTy::TyWithLocation (a), + TyTy::TyWithLocation (b), + impl_predicate.get_locus ()); rust_assert (result->get_kind () != TyTy::TypeKind::ERROR); } diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc index b809ac33108..d5121e7a7bc 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-base.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc @@ -336,6 +336,30 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, Location locus) return repr; } +TyTy::BaseType * +TypeCheckBase::unify_site (HirId id, TyTy::TyWithLocation lhs, + TyTy::TyWithLocation rhs, Location unify_locus) +{ + TyTy::BaseType *expected = lhs.get_ty (); + TyTy::BaseType *expr = rhs.get_ty (); + + rust_debug ("unify_site id={%u} expected={%s} expr={%s}", id, + expected->debug_str ().c_str (), expr->debug_str ().c_str ()); + + TyTy::BaseType *unified = expected->unify (expr); + if (unified->get_kind () == TyTy::TypeKind::ERROR) + { + RichLocation r (unify_locus); + r.add_range (lhs.get_locus ()); + r.add_range (rhs.get_locus ()); + rust_error_at (r, "expected %<%s%> got %<%s%>", + expected->get_name ().c_str (), + expr->get_name ().c_str ()); + } + + return unified; +} + TyTy::BaseType * TypeCheckBase::coercion_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs, Location locus) @@ -363,7 +387,9 @@ TypeCheckBase::coercion_site (HirId id, TyTy::TyWithLocation lhs, rust_debug ("coerce_default_unify(a={%s}, b={%s})", receiver->debug_str ().c_str (), expected->debug_str ().c_str ()); - TyTy::BaseType *coerced = expected->unify (receiver); + TyTy::BaseType *coerced + = unify_site (id, lhs, TyTy::TyWithLocation (receiver, rhs.get_locus ()), + locus); context->insert_autoderef_mappings (id, std::move (result.adjustments)); return coerced; } @@ -393,7 +419,11 @@ TypeCheckBase::cast_site (HirId id, TyTy::TyWithLocation from, rust_debug ("cast_default_unify(a={%s}, b={%s})", casted_result->debug_str ().c_str (), to.get_ty ()->debug_str ().c_str ()); - TyTy::BaseType *casted = to.get_ty ()->unify (casted_result); + + TyTy::BaseType *casted + = unify_site (id, to, + TyTy::TyWithLocation (casted_result, from.get_locus ()), + cast_locus); context->insert_cast_autoderef_mappings (id, std::move (result.adjustments)); return casted; } @@ -411,6 +441,7 @@ TypeCheckBase::resolve_generic_params ( // FIXME: Skipping Lifetime completely until better // handling. break; + case HIR::GenericParam::GenericKind::CONST: { auto param = static_cast (generic_param.get ()); @@ -422,7 +453,12 @@ TypeCheckBase::resolve_generic_params ( auto expr_type = TypeCheckExpr::Resolve ( param->get_default_expression ().get ()); - specified_type->unify (expr_type); + coercion_site ( + param->get_mappings ().get_hirid (), + TyTy::TyWithLocation (specified_type), + TyTy::TyWithLocation ( + expr_type, param->get_default_expression ()->get_locus ()), + param->get_locus ()); } context->insert_type (generic_param->get_mappings (), diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h index acdf55713d5..b8ff2cf6dc9 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-base.h +++ b/gcc/rust/typecheck/rust-hir-type-check-base.h @@ -34,6 +34,10 @@ class TypeCheckBase public: virtual ~TypeCheckBase () {} + static TyTy::BaseType *unify_site (HirId id, TyTy::TyWithLocation lhs, + TyTy::TyWithLocation rhs, + Location unify_locus); + static TyTy::BaseType *coercion_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs, Location coercion_locus); diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc index 0a99d444060..dd3cb12d17b 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc @@ -100,9 +100,9 @@ TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item) = new TyTy::ISizeType (discriminant->get_mappings ().get_hirid ()); context->insert_type (discriminant->get_mappings (), expected_ty); - auto unified = expected_ty->unify (capacity_type); - if (unified->get_kind () == TyTy::TypeKind::ERROR) - return; + unify_site (item.get_mappings ().get_hirid (), + TyTy::TyWithLocation (expected_ty), + TyTy::TyWithLocation (capacity_type), item.get_locus ()); const CanonicalPath *canonical_path = nullptr; bool ok = mappings->lookup_canonical_path (item.get_mappings ().get_nodeid (), diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index 8079c3c5cb5..a0eb1a596f7 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -158,17 +158,17 @@ void TypeCheckExpr::visit (HIR::ReturnExpr &expr) { auto fn_return_tyty = context->peek_return_type (); - rust_assert (fn_return_tyty != nullptr); - + Location expr_locus = expr.has_return_expr () ? expr.get_expr ()->get_locus () + : expr.get_locus (); TyTy::BaseType *expr_ty = expr.has_return_expr () ? TypeCheckExpr::Resolve (expr.get_expr ()) : TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ()); - infered = fn_return_tyty->unify (expr_ty); - fn_return_tyty->append_reference (expr_ty->get_ref ()); - for (auto &ref : infered->get_combined_refs ()) - fn_return_tyty->append_reference (ref); + infered = unify_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (fn_return_tyty), + TyTy::TyWithLocation (expr_ty, expr_locus), + expr.get_locus ()); infered = new TyTy::NeverType (expr.get_mappings ().get_hirid ()); } @@ -240,9 +240,12 @@ TypeCheckExpr::visit (HIR::CompoundAssignmentExpr &expr) // we dont care about the result of the unify from a compound assignment // since this is a unit-type expr - auto result = lhs->unify (rhs); - if (result->get_kind () == TyTy::TypeKind::ERROR) - return; + coercion_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (lhs, + expr.get_left_expr ()->get_locus ()), + TyTy::TyWithLocation (rhs, + expr.get_right_expr ()->get_locus ()), + expr.get_locus ()); auto lang_item_type = Analysis::RustLangItem::CompoundAssignmentOperatorToLangItem ( @@ -306,8 +309,13 @@ TypeCheckExpr::visit (HIR::ArithmeticOrLogicalExpr &expr) } break; - default: - infered = lhs->unify (rhs); + default: { + infered = unify_site ( + expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()), + TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()), + expr.get_locus ()); + } break; } } @@ -318,9 +326,10 @@ TypeCheckExpr::visit (HIR::ComparisonExpr &expr) auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ()); auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ()); - auto result = lhs->unify (rhs); - if (result == nullptr || result->get_kind () == TyTy::TypeKind::ERROR) - return; + unify_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()), + TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()), + expr.get_locus ()); bool ok = context->lookup_builtin ("bool", &infered); rust_assert (ok); @@ -333,17 +342,28 @@ TypeCheckExpr::visit (HIR::LazyBooleanExpr &expr) auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ()); // we expect the lhs and rhs must be bools at this point - TyTy::BoolType elhs (expr.get_mappings ().get_hirid ()); - lhs = elhs.unify (lhs); - if (lhs->get_kind () == TyTy::TypeKind::ERROR) - return; + TyTy::BaseType *boolean_node = nullptr; + bool ok = context->lookup_builtin ("bool", &boolean_node); + rust_assert (ok); - TyTy::BoolType rlhs (expr.get_mappings ().get_hirid ()); - rhs = elhs.unify (rhs); - if (lhs->get_kind () == TyTy::TypeKind::ERROR) - return; + // verify the lhs and rhs before unifying together + lhs = unify_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (boolean_node, + expr.get_lhs ()->get_locus ()), + TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()), + expr.get_locus ()); - infered = lhs->unify (rhs); + rhs = unify_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (boolean_node, + expr.get_rhs ()->get_locus ()), + TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()), + expr.get_locus ()); + + infered + = unify_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()), + TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()), + expr.get_locus ()); } void @@ -428,7 +448,15 @@ TypeCheckExpr::visit (HIR::IfExprConseqElse &expr) else if (else_blk_resolved->get_kind () == TyTy::NEVER) infered = if_blk_resolved; else - infered = if_blk_resolved->unify (else_blk_resolved); + { + infered = unify_site ( + expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (if_blk_resolved, + expr.get_if_block ()->get_locus ()), + TyTy::TyWithLocation (else_blk_resolved, + expr.get_else_block ()->get_locus ()), + expr.get_locus ()); + } } void @@ -443,7 +471,15 @@ TypeCheckExpr::visit (HIR::IfExprConseqIf &expr) else if (else_blk_resolved->get_kind () == TyTy::NEVER) infered = if_blk_resolved; else - infered = if_blk_resolved->unify (else_blk_resolved); + { + infered = unify_site ( + expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (if_blk_resolved, + expr.get_if_block ()->get_locus ()), + TyTy::TyWithLocation (else_blk_resolved, + expr.get_conseq_if_expr ()->get_locus ()), + expr.get_locus ()); + } } void @@ -459,9 +495,10 @@ TypeCheckExpr::visit (HIR::IfLetExpr &expr) TyTy::BaseType *kase_arm_ty = TypeCheckPattern::Resolve (pattern.get (), scrutinee_tyty); - TyTy::BaseType *checked_kase = scrutinee_tyty->unify (kase_arm_ty); - if (checked_kase->get_kind () == TyTy::TypeKind::ERROR) - return; + unify_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (scrutinee_tyty), + TyTy::TyWithLocation (kase_arm_ty, pattern->get_locus ()), + expr.get_locus ()); } TypeCheckExpr::Resolve (expr.get_if_block ()); @@ -502,7 +539,10 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr) { auto unit = TyTy::TupleType::get_unit_type (s->get_mappings ().get_hirid ()); - resolved = unit->unify (resolved); + resolved + = unify_site (s->get_mappings ().get_hirid (), + TyTy::TyWithLocation (unit), + TyTy::TyWithLocation (resolved), s->get_locus ()); } } @@ -512,7 +552,10 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr) infered = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ()); else - infered = new TyTy::NeverType (expr.get_mappings ().get_hirid ()); + { + // FIXME this seems wrong + infered = new TyTy::NeverType (expr.get_mappings ().get_hirid ()); + } } void @@ -552,7 +595,12 @@ TypeCheckExpr::visit (HIR::RangeFromToExpr &expr) TyTy::BaseType *from_ty = TypeCheckExpr::Resolve (expr.get_from_expr ().get ()); TyTy::BaseType *to_ty = TypeCheckExpr::Resolve (expr.get_to_expr ().get ()); - TyTy::BaseType *unified = from_ty->unify (to_ty); + + TyTy::BaseType *unified = unify_site ( + expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (from_ty, expr.get_from_expr ()->get_locus ()), + TyTy::TyWithLocation (to_ty, expr.get_to_expr ()->get_locus ()), + expr.get_locus ()); // substitute it in std::vector subst_mappings; @@ -722,7 +770,11 @@ TypeCheckExpr::visit (HIR::RangeFromToInclExpr &expr) TyTy::BaseType *from_ty = TypeCheckExpr::Resolve (expr.get_from_expr ().get ()); TyTy::BaseType *to_ty = TypeCheckExpr::Resolve (expr.get_to_expr ().get ()); - TyTy::BaseType *unified = from_ty->unify (to_ty); + TyTy::BaseType *unified = unify_site ( + expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (from_ty, expr.get_from_expr ()->get_locus ()), + TyTy::TyWithLocation (to_ty, expr.get_to_expr ()->get_locus ()), + expr.get_locus ()); // substitute it in std::vector subst_mappings; @@ -763,9 +815,11 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr) if (maybe_simple_array_access && direct_array_expr_ty->get_kind () == TyTy::TypeKind::ARRAY) { - auto resolved_index_expr = size_ty->unify (index_expr_ty); - if (resolved_index_expr->get_kind () == TyTy::TypeKind::ERROR) - return; + unify_site (expr.get_index_expr ()->get_mappings ().get_hirid (), + TyTy::TyWithLocation (size_ty), + TyTy::TyWithLocation (index_expr_ty, + expr.get_index_expr ()->get_locus ()), + expr.get_locus ()); TyTy::ArrayType *array_type = static_cast (direct_array_expr_ty); @@ -821,9 +875,11 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr) context->insert_type (elems.get_num_copies_expr ()->get_mappings (), expected_ty); - auto unified = expected_ty->unify (capacity_type); - if (unified->get_kind () == TyTy::TypeKind::ERROR) - return; + unify_site ( + expr.get_mappings ().get_hirid (), TyTy::TyWithLocation (expected_ty), + TyTy::TyWithLocation (capacity_type, + elems.get_num_copies_expr ()->get_locus ()), + expr.get_locus ()); capacity_expr = elems.get_num_copies_expr (); } @@ -839,11 +895,16 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr) types.push_back (TypeCheckExpr::Resolve (elem.get ())); } + // this is a LUB element_type = TyTy::TyVar::get_implicit_infer_var (expr.get_locus ()).get_tyty (); for (auto &type : types) { - element_type = element_type->unify (type); + element_type + = unify_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (element_type), + TyTy::TyWithLocation (type, type->get_locus ()), + expr.get_locus ()); } auto crate_num = mappings->get_current_crate (); @@ -1165,7 +1226,12 @@ TypeCheckExpr::visit (HIR::BreakExpr &expr) return; } - TyTy::BaseType *unified_ty = loop_context->unify (break_expr_tyty); + TyTy::BaseType *unified_ty + = unify_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (loop_context), + TyTy::TyWithLocation (break_expr_tyty, + expr.get_expr ()->get_locus ()), + expr.get_locus ()); context->swap_head_loop_context (unified_ty); } @@ -1290,7 +1356,12 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr) TyTy::BaseType *kase_arm_ty = TypeCheckPattern::Resolve (pattern.get (), scrutinee_tyty); - TyTy::BaseType *checked_kase = scrutinee_tyty->unify (kase_arm_ty); + TyTy::BaseType *checked_kase = unify_site ( + expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (scrutinee_tyty, + expr.get_scrutinee_expr ()->get_locus ()), + TyTy::TyWithLocation (kase_arm_ty, pattern->get_locus ()), + expr.get_locus ()); if (checked_kase->get_kind () == TyTy::TypeKind::ERROR) return; } @@ -1308,13 +1379,14 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr) return; } + // this is a LUB infered = kase_block_tys.at (0); for (size_t i = 1; i < kase_block_tys.size (); i++) { TyTy::BaseType *kase_ty = kase_block_tys.at (i); - infered = infered->unify (kase_ty); - if (infered->get_kind () == TyTy::TypeKind::ERROR) - return; + infered = unify_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (infered), + TyTy::TyWithLocation (kase_ty), expr.get_locus ()); } } @@ -1470,7 +1542,11 @@ TypeCheckExpr::resolve_operator_overload ( TyTy::FnType *type = static_cast (lookup); rust_assert (type->num_params () > 0); auto fnparam = type->param_at (0); - fnparam.second->unify (adjusted_self); // typecheck the self + + // typecheck the self + unify_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (fnparam.second), + TyTy::TyWithLocation (adjusted_self), expr.get_locus ()); if (rhs == nullptr) { rust_assert (type->num_params () == 1); @@ -1479,7 +1555,9 @@ TypeCheckExpr::resolve_operator_overload ( { rust_assert (type->num_params () == 2); auto fnparam = type->param_at (1); - fnparam.second->unify (rhs); // typecheck the rhs + unify_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (fnparam.second), + TyTy::TyWithLocation (rhs), expr.get_locus ()); } rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF); diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc index 1b99552e94b..f1f56d28ae2 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc @@ -179,7 +179,12 @@ TypeCheckTopLevelImplItem::visit (HIR::ConstantItem &constant) TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ()); TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ()); - context->insert_type (constant.get_mappings (), type->unify (expr_type)); + TyTy::BaseType *unified = unify_site ( + constant.get_mappings ().get_hirid (), + TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()), + TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()), + constant.get_locus ()); + context->insert_type (constant.get_mappings (), unified); } void @@ -365,8 +370,16 @@ TypeCheckImplItem::visit (HIR::Function &function) auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ().get ()); + Location fn_return_locus = function.has_function_return_type () + ? function.get_return_type ()->get_locus () + : function.get_locus (); + + coercion_site (function.get_definition ()->get_mappings ().get_hirid (), + TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus), + TyTy::TyWithLocation (block_expr_ty), + function.get_definition ()->get_locus ()); + context->pop_return_type (); - expected_ret_tyty->unify (block_expr_ty); } void diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc index 97a894b1b29..0aa26072efc 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-item.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc @@ -214,10 +214,15 @@ TypeCheckItem::visit (HIR::Function &function) auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ().get ()); - context->pop_return_type (); + Location fn_return_locus = function.has_function_return_type () + ? function.get_return_type ()->get_locus () + : function.get_locus (); + coercion_site (function.get_definition ()->get_mappings ().get_hirid (), + TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus), + TyTy::TyWithLocation (block_expr_ty), + function.get_definition ()->get_locus ()); - if (block_expr_ty->get_kind () != TyTy::NEVER) - expected_ret_tyty->unify (block_expr_ty); + context->pop_return_type (); } void diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc index 765f8b21aa5..bf1de21ee4f 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-path.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc @@ -390,7 +390,10 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id, impl_block_ty = SubstMapper::InferSubst (impl_block_ty, seg.get_locus ()); - prev_segment = prev_segment->unify (impl_block_ty); + prev_segment = unify_site (seg.get_mappings ().get_hirid (), + TyTy::TyWithLocation (prev_segment), + TyTy::TyWithLocation (impl_block_ty), + seg.get_locus ()); } if (tyseg->needs_generic_substitutions ()) diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc index 118cee811ce..82af7294d69 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc @@ -375,7 +375,9 @@ TypeCheckPattern::visit (HIR::RangePattern &pattern) break; } - infered = upper->unify (lower); + infered = unify_site (pattern.get_pattern_mappings ().get_hirid (), + TyTy::TyWithLocation (upper), + TyTy::TyWithLocation (lower), pattern.get_locus ()); } void diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.cc b/gcc/rust/typecheck/rust-hir-type-check-stmt.cc index 2b4925383e5..e82dd8e5300 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-stmt.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.cc @@ -68,7 +68,11 @@ TypeCheckStmt::visit (HIR::ConstantItem &constant) TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ()); TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ()); - infered = type->unify (expr_type); + infered = unify_site ( + constant.get_mappings ().get_hirid (), + TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()), + TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()), + constant.get_locus ()); context->insert_type (constant.get_mappings (), infered); } @@ -498,8 +502,13 @@ TypeCheckStmt::visit (HIR::Function &function) context->pop_return_type (); - if (block_expr_ty->get_kind () != TyTy::NEVER) - expected_ret_tyty->unify (block_expr_ty); + Location fn_return_locus = function.has_function_return_type () + ? function.get_return_type ()->get_locus () + : function.get_locus (); + coercion_site (function.get_definition ()->get_mappings ().get_hirid (), + TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus), + TyTy::TyWithLocation (block_expr_ty), + function.get_definition ()->get_locus ()); infered = fnType; } diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct.cc b/gcc/rust/typecheck/rust-hir-type-check-struct.cc index 38fd5e28c0d..259d4ca182e 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-struct.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-struct.cc @@ -57,14 +57,20 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr) { TyTy::BaseType *base_resolved = TypeCheckExpr::Resolve (struct_expr.struct_base->base_struct.get ()); - struct_def = static_cast ( - struct_path_resolved->unify (base_resolved)); - if (struct_def == nullptr) + TyTy::BaseType *base_unify = unify_site ( + struct_expr.struct_base->base_struct->get_mappings ().get_hirid (), + TyTy::TyWithLocation (struct_path_resolved), + TyTy::TyWithLocation (base_resolved), + struct_expr.struct_base->base_struct->get_locus ()); + + if (base_unify->get_kind () != struct_path_ty->get_kind ()) { rust_fatal_error (struct_expr.struct_base->base_struct->get_locus (), "incompatible types for base struct reference"); return; } + + struct_def = static_cast (base_unify); } // figure out the variant diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc b/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc index dd9abdd7d0d..b0ee292df10 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc @@ -260,7 +260,13 @@ TypeCheckTopLevel::visit (HIR::StaticItem &var) TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ()); TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ()); - context->insert_type (var.get_mappings (), type->unify (expr_type)); + TyTy::BaseType *unified + = unify_site (var.get_mappings ().get_hirid (), + TyTy::TyWithLocation (type, var.get_type ()->get_locus ()), + TyTy::TyWithLocation (expr_type, + var.get_expr ()->get_locus ()), + var.get_locus ()); + context->insert_type (var.get_mappings (), unified); } void @@ -269,7 +275,12 @@ TypeCheckTopLevel::visit (HIR::ConstantItem &constant) TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ()); TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ()); - context->insert_type (constant.get_mappings (), type->unify (expr_type)); + TyTy::BaseType *unified = unify_site ( + constant.get_mappings ().get_hirid (), + TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()), + TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()), + constant.get_locus ()); + context->insert_type (constant.get_mappings (), unified); } void diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index 46e465ca2d4..06dc8e042d9 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -623,9 +623,11 @@ TypeCheckType::visit (HIR::ArrayType &type) rust_assert (ok); context->insert_type (type.get_size_expr ()->get_mappings (), expected_ty); - auto unified = expected_ty->unify (capacity_type); - if (unified->get_kind () == TyTy::TypeKind::ERROR) - return; + unify_site (type.get_size_expr ()->get_mappings ().get_hirid (), + TyTy::TyWithLocation (expected_ty), + TyTy::TyWithLocation (capacity_type, + type.get_size_expr ()->get_locus ()), + type.get_size_expr ()->get_locus ()); TyTy::BaseType *base = TypeCheckType::Resolve (type.get_element_type ()); translated = new TyTy::ArrayType (type.get_mappings ().get_hirid (), diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc index fb71cfb8e02..f2445cd3ba2 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.cc +++ b/gcc/rust/typecheck/rust-hir-type-check.cc @@ -70,7 +70,12 @@ TypeResolution::Resolve (HIR::Crate &crate) } else { - auto result = ty->unify (default_type); + auto result + = TypeCheckBase::unify_site (id, TyTy::TyWithLocation (ty), + TyTy::TyWithLocation (default_type), + Location ()); + rust_assert (result); + rust_assert (result->get_kind () != TyTy::TypeKind::ERROR); result->set_ref (id); context->insert_type ( Analysis::NodeMapping (mappings->get_current_crate (), 0, id, @@ -144,7 +149,10 @@ TraitItemReference::get_type_from_constant ( TyTy::BaseType *expr = TypeCheckExpr::Resolve (constant.get_expr ().get ()); - return type->unify (expr); + return TypeCheckBase::unify_site (constant.get_mappings ().get_hirid (), + TyTy::TyWithLocation (type), + TyTy::TyWithLocation (expr), + constant.get_locus ()); } return type; } diff --git a/gcc/rust/typecheck/rust-tyctx.cc b/gcc/rust/typecheck/rust-tyctx.cc index af86b064c6c..a0b5c5e849e 100644 --- a/gcc/rust/typecheck/rust-tyctx.cc +++ b/gcc/rust/typecheck/rust-tyctx.cc @@ -129,6 +129,7 @@ TypeCheckContext::lookup_type_by_node_id (NodeId ref, HirId *id) TyTy::BaseType * TypeCheckContext::peek_return_type () { + rust_assert (!return_type_stack.empty ()); return return_type_stack.back ().second; } diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc index 70bc3d3c2a0..96c6b93e5c2 100644 --- a/gcc/rust/typecheck/rust-tyty-call.cc +++ b/gcc/rust/typecheck/rust-tyty-call.cc @@ -219,7 +219,10 @@ TypeCheckCallExpr::visit (FnPtr &type) void TypeCheckMethodCallExpr::visit (FnType &type) { - type.get_self_type ()->unify (adjusted_self); + Resolver::TypeCheckBase::unify_site ( + call.get_mappings ().get_hirid (), TyWithLocation (type.get_self_type ()), + TyWithLocation (adjusted_self, call.get_receiver ()->get_locus ()), + call.get_locus ()); // +1 for the receiver self size_t num_args_to_call = call.num_params () + 1; diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h index 485546e2c05..2813bf42c1c 100644 --- a/gcc/rust/typecheck/rust-tyty-cmp.h +++ b/gcc/rust/typecheck/rust-tyty-cmp.h @@ -1243,8 +1243,8 @@ public: auto base_type = base->get_base (); auto other_base_type = type.get_base (); - bool mutability_match = base->is_mutable () == type.is_mutable (); - if (!mutability_match) + bool mutability_ok = base->is_mutable () ? type.is_mutable () : true; + if (!mutability_ok) { BaseCmp::visit (type); return; diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h index 8cf96409d14..7ffffc1dd59 100644 --- a/gcc/rust/typecheck/rust-tyty-rules.h +++ b/gcc/rust/typecheck/rust-tyty-rules.h @@ -123,269 +123,53 @@ public: return resolved; } - virtual void visit (TupleType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (TupleType &type) override {} - virtual void visit (ADTType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (ADTType &type) override {} - virtual void visit (InferType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (InferType &type) override {} - virtual void visit (FnType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (FnType &type) override {} - virtual void visit (FnPtr &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (FnPtr &type) override {} - virtual void visit (ArrayType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (ArrayType &type) override {} - virtual void visit (SliceType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (SliceType &type) override {} - virtual void visit (BoolType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (BoolType &type) override {} - virtual void visit (IntType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (IntType &type) override {} - virtual void visit (UintType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (UintType &type) override {} - virtual void visit (USizeType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (USizeType &type) override {} - virtual void visit (ISizeType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (ISizeType &type) override {} - virtual void visit (FloatType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (FloatType &type) override {} - virtual void visit (ErrorType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (ErrorType &type) override {} - virtual void visit (CharType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (CharType &type) override {} - virtual void visit (ReferenceType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (ReferenceType &type) override {} - virtual void visit (PointerType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (PointerType &type) override {} - virtual void visit (ParamType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (ParamType &type) override {} - virtual void visit (StrType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (StrType &type) override {} - virtual void visit (NeverType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (NeverType &type) override {} - virtual void visit (PlaceholderType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (PlaceholderType &type) override {} - virtual void visit (ProjectionType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (ProjectionType &type) override {} - virtual void visit (DynamicObjectType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (DynamicObjectType &type) override {} - virtual void visit (ClosureType &type) override - { - Location ref_locus = mappings->lookup_location (type.get_ref ()); - Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); - RichLocation r (ref_locus); - r.add_range (base_locus); - rust_error_at (r, "expected [%s] got [%s]", - get_base ()->as_string ().c_str (), - type.as_string ().c_str ()); - } + virtual void visit (ClosureType &type) override {} protected: BaseRules (BaseType *base) diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 42c021e3aa1..3e29bd2a92c 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -296,6 +296,33 @@ BaseType::destructure () const return x; } +std::string +BaseType::mappings_str () const +{ + std::string buffer = "Ref: " + std::to_string (get_ref ()) + + " TyRef: " + std::to_string (get_ty_ref ()); + buffer += "["; + for (auto &ref : combined) + buffer += std::to_string (ref) + ","; + buffer += "]"; + return "(" + buffer + ")"; +} + +std::string +BaseType::debug_str () const +{ + // return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":" + // + mappings_str () + ":" + bounds_as_string (); + return get_name (); +} + +void +BaseType::debug () const +{ + rust_debug ("[%p] %s", static_cast (this), + debug_str ().c_str ()); +} + TyVar::TyVar (HirId ref) : ref (ref) { // ensure this reference is defined within the context @@ -1159,11 +1186,29 @@ TupleType::accept_vis (TyConstVisitor &vis) const std::string TupleType::as_string () const { + size_t i = 0; + std::string fields_buffer; + for (const TyVar &field : get_fields ()) + { + fields_buffer += field.get_tyty ()->as_string (); + bool has_next = (i + 1) < get_fields ().size (); + fields_buffer += has_next ? ", " : ""; + i++; + } + return "(" + fields_buffer + ")"; +} + +std::string +TupleType::get_name () const +{ + size_t i = 0; std::string fields_buffer; for (const TyVar &field : get_fields ()) { fields_buffer += field.get_tyty ()->as_string (); - fields_buffer += ", "; + bool has_next = (i + 1) < get_fields ().size (); + fields_buffer += has_next ? ", " : ""; + i++; } return "(" + fields_buffer + ")"; } @@ -2194,6 +2239,13 @@ ReferenceType::as_string () const + get_base ()->as_string (); } +std::string +ReferenceType::get_name () const +{ + return std::string ("&") + (is_mutable () ? "mut" : "") + " " + + get_base ()->get_name (); +} + BaseType * ReferenceType::unify (BaseType *other) { @@ -2277,6 +2329,13 @@ PointerType::as_string () const + get_base ()->as_string (); } +std::string +PointerType::get_name () const +{ + return std::string ("* ") + (is_mutable () ? "mut" : "const") + " " + + get_base ()->get_name (); +} + BaseType * PointerType::unify (BaseType *other) { diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 9252d2affc9..14868f2bb81 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -230,28 +230,11 @@ public: bool contains_type_parameters () const { return !is_concrete (); } - std::string mappings_str () const - { - std::string buffer = "Ref: " + std::to_string (get_ref ()) - + " TyRef: " + std::to_string (get_ty_ref ()); - buffer += "["; - for (auto &ref : combined) - buffer += std::to_string (ref) + ","; - buffer += "]"; - return "(" + buffer + ")"; - } + std::string mappings_str () const; - std::string debug_str () const - { - return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":" - + mappings_str () + ":" + bounds_as_string (); - } + std::string debug_str () const; - void debug () const - { - rust_debug ("[%p] %s", static_cast (this), - debug_str ().c_str ()); - } + void debug () const; // FIXME this will eventually go away const BaseType *get_root () const; @@ -560,7 +543,7 @@ public: const std::vector &get_fields () const { return fields; } - std::string get_name () const override final { return as_string (); } + std::string get_name () const override final; TupleType *handle_substitions (SubstitutionArgumentMappings mappings); @@ -2164,10 +2147,7 @@ public: std::string as_string () const override; - std::string get_name () const override final - { - return "&" + get_base ()->get_name (); - } + std::string get_name () const override final; BaseType *unify (BaseType *other) override; bool can_eq (const BaseType *other, bool emit_errors) const override final; @@ -2249,11 +2229,7 @@ public: void accept_vis (TyConstVisitor &vis) const override; std::string as_string () const override; - - std::string get_name () const override final - { - return "*" + get_base ()->get_name (); - } + std::string get_name () const override final; BaseType *unify (BaseType *other) override; bool can_eq (const BaseType *other, bool emit_errors) const override final; diff --git a/gcc/testsuite/rust/compile/issue-1152.rs b/gcc/testsuite/rust/compile/issue-1152.rs index 18eee9e6b4a..15697057ec6 100644 --- a/gcc/testsuite/rust/compile/issue-1152.rs +++ b/gcc/testsuite/rust/compile/issue-1152.rs @@ -1,8 +1,6 @@ fn test() { let f = [0; -4_isize]; // { dg-error "expected .usize. got .isize." "" { target *-*-* } .-1 } - // { dg-error "failed to type resolve expression" "" { target *-*-* } .-2 } let f = [0_usize; -1_isize]; // { dg-error "expected .usize. got .isize." "" { target *-*-* } .-1 } - // { dg-error "failed to type resolve expression" "" { target *-*-* } .-2 } } diff --git a/gcc/testsuite/rust/compile/tuple1.rs b/gcc/testsuite/rust/compile/tuple1.rs index 84179b13727..0e381dc6ca4 100644 --- a/gcc/testsuite/rust/compile/tuple1.rs +++ b/gcc/testsuite/rust/compile/tuple1.rs @@ -1,5 +1,5 @@ fn main() { - let a: (i32, bool) = (123, 123); // { dg-error "expected .bool. got .." } + let a: (i32, bool) = (123, 123); // { dg-error "expected" } let b; b = (456, 5f32); } diff --git a/gcc/testsuite/rust/compile/type-alias1.rs b/gcc/testsuite/rust/compile/type-alias1.rs index c7d7048246a..7d038cac469 100644 --- a/gcc/testsuite/rust/compile/type-alias1.rs +++ b/gcc/testsuite/rust/compile/type-alias1.rs @@ -2,5 +2,5 @@ type TypeAlias = (i32, u32); fn main() { let a: TypeAlias; - a = (123, 456f32); // { dg-error "expected .u32. got .f32." } + a = (123, 456f32); // { dg-error "expected" } } diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_9.rs b/gcc/testsuite/rust/execute/torture/operator_overload_9.rs index fd972e28ab3..fbb96a60d36 100644 --- a/gcc/testsuite/rust/execute/torture/operator_overload_9.rs +++ b/gcc/testsuite/rust/execute/torture/operator_overload_9.rs @@ -1,4 +1,4 @@ -/* { dg-output "mut_deref\n123\n" } */ +/* { dg-output "imm_deref\n123\n" } */ extern "C" { fn printf(s: *const i8, ...); } diff --git a/gcc/testsuite/rust/execute/torture/slice1.rs b/gcc/testsuite/rust/execute/torture/slice1.rs index a0488b3912c..206082af624 100644 --- a/gcc/testsuite/rust/execute/torture/slice1.rs +++ b/gcc/testsuite/rust/execute/torture/slice1.rs @@ -12,9 +12,10 @@ union Repr { const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { unsafe { - let a = FatPtr { data, len }; - let b = Repr { raw: a }; - b.rust + Repr { + raw: FatPtr { data, len }, + } + .rust } } -- 2.39.1