From patchwork Tue Feb 21 12:01:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arthur Cohen X-Patchwork-Id: 59978 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp1829165wrn; Tue, 21 Feb 2023 04:18:04 -0800 (PST) X-Google-Smtp-Source: AK7set8fDRHdeCgvofcXE1ZLYy+uEgqQJpOyHCx5WUZRUDdUCH2PtptSf/c7GMFd4gAq81SmmhBi X-Received: by 2002:a17:906:bcd8:b0:8b1:2bde:5c70 with SMTP id lw24-20020a170906bcd800b008b12bde5c70mr13115750ejb.2.1676981884553; Tue, 21 Feb 2023 04:18:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676981884; cv=none; d=google.com; s=arc-20160816; b=g98K32PaVZWOgQog2oQ/zPQdXg1z2rAKUu+sgvbyPaKhbFDT76AxaH+y6xPwsj7LNy /MNm6tdDOxvD2I8DqiGWgjBSTArElthAL6/WEZ4LfRZZs+kI4a3FVmMhaJjAH/8JqEwq p6Hg53mzw6Nn7W8HojME2z8neQRxaX/YVObn0MEGFh228lQWQp6lA3W3LUIdY3csSLNS CT7CsnmCYPsslbCTlJJo1ZpE+jMVWF2QE5cNKGCUsJersaN++mrfFDTj7GJa9OX6sxmh nGLIFzoiY7R1gCy/6Rgcr/I3h79KCJb34m9fQqsU8vTBNxBRl1/wv4NJCuKDDlKAvk2z SnPA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:dmarc-filter :delivered-to; bh=TOP34unwJwUagxyVW0QAXQemUlwOVdeI9VVsZKH6Baw=; b=Ct+BHyhc0DMI8gPuHzxAGFDl4QGs8UKLOBFsVTTEWRVA3LDdZ7kug1fCH+Pzq44DOs DiUAYwlQPodRlLo96RGCesFfo1XOQ+H4zQSGFJB0Xv0tfaM3BFkK0oMXHnEUC7x2Atgo pC0x9Q3f3JDXX7aDICRn+KpgktfNmn+mk/PtLw5fXBaj+eijX8KA7E9bnlW00tJGJXCS xkdAGdoFpRwzVyMcwnmhUkFUCfPq5L+Xz/YNPPa6wQcKfQtVVgrN22aRkAw5G4sinbhX 4cOI7t2uAnEr/H3rl5oqHOKe+zG4EZWSoCWYOps1AFHzL0/DJOcGO9BL+TvSp67tVnih ZmOA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@embecosm.com header.s=google header.b="YYpI2/f5"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id k24-20020a05640212d800b004acb31af1e8si18173458edx.561.2023.02.21.04.18.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Feb 2023 04:18:04 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@embecosm.com header.s=google header.b="YYpI2/f5"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EF9AC39960F7 for ; Tue, 21 Feb 2023 12:08:17 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by sourceware.org (Postfix) with ESMTPS id 36C08383FE03 for ; Tue, 21 Feb 2023 12:03:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 36C08383FE03 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-wr1-x436.google.com with SMTP id c12so4162418wrw.1 for ; Tue, 21 Feb 2023 04:03:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=TOP34unwJwUagxyVW0QAXQemUlwOVdeI9VVsZKH6Baw=; b=YYpI2/f5Nlc0qTsm0Qe9GZBNeNx0Rp7onMyKO8DkzO6zFmIGo2uD+PQ+TR7DmSC3IN bMCQTpzRszvErzchgTm2Ui1b7ytmjHJFwP8XZg1Ney1+Y1s9xyLShDL4Nq1062QGaKMu vcItBNAR+TY4IrHsMh799yi2mu5wXuZUI12ZDGLAZMS+dpYM67PWTv8GATxOzjHzoRrT JDTMP7qr+z9u/8bmKcRGIGC2FBb6BnV+t+q1wKjM5hWDy+H4HUVyK3Qc7MfOxZWvf5ED DDijT30Y2cP8JNdREqvQuxmGG4afZ1sou1YGpbu+sTUFbpG3Qi2XktU1nr8oakPU6rLR b1RQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=TOP34unwJwUagxyVW0QAXQemUlwOVdeI9VVsZKH6Baw=; b=xt5xasBL2avCTQe/FoSmF1M6W7vq17SVw4MsUBUfeDQayhKmaGj9tArgk5kKefDQLo YtypiU9xmLhxDMQCDj19c+EPwfd+hv6KrHT7agwal55p69tMQbMNuMdeF+DkgVdSimdp fIZAgVly/yphpWOWelYAQbt7SusCkJ+jNUK5QdegT1h9XyeccJ4YWi0azCDrxX2b+Ct2 ea0FcJT/djdcGxMzJ4VPN2BEXEFf7u4HZ8HVcMbC4+68Ex4vfVo9ZsVbZOeNHFwsY4g+ nIjaweHxEfzfedDM5VUTgnZ4kBgu1m6ynyyK+fv1GRJUl445DysnT0vf95jYPdiX+yzH KMLw== X-Gm-Message-State: AO0yUKVf24IavSg8oRF9qHCxuUz8YzKhWydhhE7KuqCc46AYsDpoL1kP NuB2vAUvUGyeDjDDW2UOadyYZS8zSYvcK04Ahw== X-Received: by 2002:adf:e389:0:b0:2c3:e0a0:93f with SMTP id e9-20020adfe389000000b002c3e0a0093fmr3963886wrm.8.1676981023404; Tue, 21 Feb 2023 04:03:43 -0800 (PST) Received: from platypus.localdomain ([62.23.166.218]) by smtp.gmail.com with ESMTPSA id c15-20020adffb4f000000b002c55b0e6ef1sm5013811wrs.4.2023.02.21.04.03.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Feb 2023 04:03:42 -0800 (PST) From: arthur.cohen@embecosm.com To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Philip Herron Subject: [committed 024/103] gccrs: Method resolution must support multiple candidates Date: Tue, 21 Feb 2023 13:01:14 +0100 Message-Id: <20230221120230.596966-25-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230221120230.596966-1-arthur.cohen@embecosm.com> References: <20230221120230.596966-1-arthur.cohen@embecosm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-14.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: arthur.cohen@embecosm.com Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1758442956507981635?= X-GMAIL-MSGID: =?utf-8?q?1758442956507981635?= From: Philip Herron This patch fixes bad method resolution in our operator_overload_9 case. When we have a &mut reference to something and we deref we must resolve to the mutable reference impl block. The interface we are using to resolve methods is the can_eq interface which allows for permissive mutability which means allowing for mutable reference being unified with an immutable one. This meant we actual match against both the immutable and mutable version leading to multiple candidate error. The fix here adds a method resolution flag to the can_eq interface so that we enforce mutability equality. The other hack is that we do not allow can_eq of ParamTypes to generic Slices. I think there is some subtle thing going on for that case. The Rustc method resolver actually filters the impl blocks for reference types based looking up the relevant lang items we need to do this as well but is a much larger refactor to our method resolver which should be done seperately. Fixes #1588 gcc/rust/ChangeLog: * typecheck/rust-autoderef.cc: Add support for multiple resolution candidates. * typecheck/rust-hir-dot-operator.cc (MethodResolver::MethodResolver): Edit `try_result` field and change constructor. (MethodResolver::Probe): Return set of candidates instead of singular candidate. (MethodResolver::select): Add better implementation to account for multiple candidates. * typecheck/rust-hir-dot-operator.h (struct MethodCandidate): Overload comparison operator in order to store them in `std::set`. * typecheck/rust-hir-inherent-impl-overlap.h: Do not fail assertion on missing type. * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Adapt code to use multiple candidates. * typecheck/rust-tyty.cc (set_cmp_autoderef_mode): Add code to handle automatic derefs properly. (reset_cmp_autoderef_mode): Add helper function to reset said mode. * typecheck/rust-tyty.h (set_cmp_autoderef_mode): Declare function. (reset_cmp_autoderef_mode): Likewise. * typecheck/rust-tyty-cmp.h: Add handling of `autoderef_cmp_flag` gcc/testsuite/ChangeLog: * rust/compile/generics7.rs: Fix test with missing assertion. * rust/execute/torture/operator_overload_9.rs: Fix test assertion. --- gcc/rust/typecheck/rust-autoderef.cc | 12 ++- gcc/rust/typecheck/rust-hir-dot-operator.cc | 80 ++++++++++++++++--- gcc/rust/typecheck/rust-hir-dot-operator.h | 16 +++- .../rust-hir-inherent-impl-overlap.h | 5 +- .../typecheck/rust-hir-type-check-expr.cc | 35 +++++++- gcc/rust/typecheck/rust-tyty-cmp.h | 14 +++- gcc/rust/typecheck/rust-tyty.cc | 13 +++ gcc/rust/typecheck/rust-tyty.h | 5 ++ gcc/testsuite/rust/compile/generics7.rs | 6 +- .../execute/torture/operator_overload_9.rs | 2 +- 10 files changed, 157 insertions(+), 31 deletions(-) diff --git a/gcc/rust/typecheck/rust-autoderef.cc b/gcc/rust/typecheck/rust-autoderef.cc index ca43f847e98..fe05aeec388 100644 --- a/gcc/rust/typecheck/rust-autoderef.cc +++ b/gcc/rust/typecheck/rust-autoderef.cc @@ -139,15 +139,23 @@ resolve_operator_overload_fn ( return false; auto segment = HIR::PathIdentSegment (associated_item_name); - auto candidate + auto candidates = MethodResolver::Probe (ty, HIR::PathIdentSegment (associated_item_name), true); - bool have_implementation_for_lang_item = !candidate.is_error (); + bool have_implementation_for_lang_item = !candidates.empty (); if (!have_implementation_for_lang_item) return false; + // multiple candidates? + if (candidates.size () > 1) + { + // error out? probably not for this case + return false; + } + // Get the adjusted self + auto candidate = *candidates.begin (); Adjuster adj (ty); TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments); diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc b/gcc/rust/typecheck/rust-hir-dot-operator.cc index ed2df11da45..84fa8d4f08b 100644 --- a/gcc/rust/typecheck/rust-hir-dot-operator.cc +++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc @@ -25,18 +25,17 @@ namespace Resolver { MethodResolver::MethodResolver (bool autoderef_flag, const HIR::PathIdentSegment &segment_name) - : AutoderefCycle (autoderef_flag), segment_name (segment_name), - try_result (MethodCandidate::get_error ()) + : AutoderefCycle (autoderef_flag), segment_name (segment_name), result () {} -MethodCandidate +std::set MethodResolver::Probe (const TyTy::BaseType *receiver, const HIR::PathIdentSegment &segment_name, bool autoderef_flag) { MethodResolver resolver (autoderef_flag, segment_name); - bool ok = resolver.cycle (receiver); - return ok ? resolver.try_result : MethodCandidate::get_error (); + resolver.cycle (receiver); + return resolver.result; } void @@ -177,8 +176,18 @@ MethodResolver::select (const TyTy::BaseType &receiver) (unsigned long) trait_fns.size (), (unsigned long) predicate_items.size ()); - for (auto impl_item : inherent_impl_fns) + // see the follow for the proper fix to get rid of this we need to assemble + // candidates based on a match expression gathering the relevant impl blocks + // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/method/probe.rs#L580-L694 + TyTy::set_cmp_autoderef_mode (); + + bool found_possible_candidate = false; + for (auto &impl_item : inherent_impl_fns) { + bool is_trait_impl_block = impl_item.impl_block->has_trait_ref (); + if (is_trait_impl_block) + continue; + TyTy::FnType *fn = impl_item.ty; rust_assert (fn->is_method ()); @@ -190,13 +199,50 @@ MethodResolver::select (const TyTy::BaseType &receiver) { PathProbeCandidate::ImplItemCandidate c{impl_item.item, impl_item.impl_block}; - try_result = MethodCandidate{ + auto try_result = MethodCandidate{ PathProbeCandidate (PathProbeCandidate::CandidateType::IMPL_FUNC, fn, impl_item.item->get_locus (), c), adjustments}; - return true; + result.insert (std::move (try_result)); + found_possible_candidate = true; } } + if (found_possible_candidate) + { + TyTy::reset_cmp_autoderef_mode (); + return true; + } + + for (auto &impl_item : inherent_impl_fns) + { + bool is_trait_impl_block = impl_item.impl_block->has_trait_ref (); + if (!is_trait_impl_block) + continue; + + TyTy::FnType *fn = impl_item.ty; + rust_assert (fn->is_method ()); + + TyTy::BaseType *fn_self = fn->get_self_type (); + rust_debug ( + "dot-operator trait_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, + impl_item.impl_block}; + auto try_result = MethodCandidate{ + PathProbeCandidate (PathProbeCandidate::CandidateType::IMPL_FUNC, + fn, impl_item.item->get_locus (), c), + adjustments}; + result.insert (std::move (try_result)); + found_possible_candidate = true; + } + } + if (found_possible_candidate) + { + TyTy::reset_cmp_autoderef_mode (); + return true; + } for (auto trait_item : trait_fns) { @@ -212,13 +258,19 @@ MethodResolver::select (const TyTy::BaseType &receiver) PathProbeCandidate::TraitItemCandidate c{trait_item.reference, trait_item.item_ref, nullptr}; - try_result = MethodCandidate{ + auto try_result = MethodCandidate{ PathProbeCandidate (PathProbeCandidate::CandidateType::TRAIT_FUNC, fn, trait_item.item->get_locus (), c), adjustments}; - return true; + result.insert (std::move (try_result)); + found_possible_candidate = true; } } + if (found_possible_candidate) + { + TyTy::reset_cmp_autoderef_mode (); + return true; + } for (const auto &predicate : predicate_items) { @@ -238,15 +290,17 @@ MethodResolver::select (const TyTy::BaseType &receiver) PathProbeCandidate::TraitItemCandidate c{trait_ref, trait_item, nullptr}; - try_result = MethodCandidate{ + auto try_result = MethodCandidate{ PathProbeCandidate (PathProbeCandidate::CandidateType::TRAIT_FUNC, fn->clone (), trait_item->get_locus (), c), adjustments}; - return true; + result.insert (std::move (try_result)); + found_possible_candidate = true; } } - return false; + TyTy::reset_cmp_autoderef_mode (); + return found_possible_candidate; } std::vector diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.h b/gcc/rust/typecheck/rust-hir-dot-operator.h index 8341173a061..e14baf3f87d 100644 --- a/gcc/rust/typecheck/rust-hir-dot-operator.h +++ b/gcc/rust/typecheck/rust-hir-dot-operator.h @@ -35,6 +35,13 @@ struct MethodCandidate } bool is_error () const { return candidate.is_error (); } + + DefId get_defid () const { return candidate.get_defid (); } + + bool operator< (const MethodCandidate &c) const + { + return get_defid () < c.get_defid (); + } }; class MethodResolver : private TypeCheckBase, protected AutoderefCycle @@ -46,9 +53,10 @@ public: TyTy::FnType *fntype; }; - static MethodCandidate Probe (const TyTy::BaseType *receiver, - const HIR::PathIdentSegment &segment_name, - bool autoderef_flag = false); + static std::set + Probe (const TyTy::BaseType *receiver, + const HIR::PathIdentSegment &segment_name, + bool autoderef_flag = false); static std::vector get_predicate_items ( const HIR::PathIdentSegment &segment_name, const TyTy::BaseType &receiver, @@ -68,7 +76,7 @@ private: std::vector predicate_items; // mutable fields - MethodCandidate try_result; + std::set result; }; } // namespace Resolver diff --git a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h index 3733f555cfb..6e2fe1b2286 100644 --- a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h +++ b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h @@ -93,8 +93,9 @@ public: HirId impl_type_id = impl->get_type ()->get_mappings ().get_hirid (); TyTy::BaseType *impl_type = nullptr; - bool ok = context->lookup_type (impl_type_id, &impl_type); - rust_assert (ok); + bool ok = query_type (impl_type_id, &impl_type); + if (!ok) + return; std::string impl_item_name; ok = ImplItemToName::resolve (impl_item, impl_item_name); diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index 2f22c82f063..4e377d52a0f 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -1015,10 +1015,10 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr) context->insert_receiver (expr.get_mappings ().get_hirid (), receiver_tyty); - auto candidate + auto candidates = MethodResolver::Probe (receiver_tyty, expr.get_method_name ().get_segment ()); - if (candidate.is_error ()) + if (candidates.empty ()) { rust_error_at ( expr.get_method_name ().get_locus (), @@ -1027,6 +1027,19 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr) return; } + if (candidates.size () > 1) + { + RichLocation r (expr.get_method_name ().get_locus ()); + for (auto &c : candidates) + r.add_range (c.candidate.locus); + + rust_error_at ( + r, "multiple candidates found for method %<%s%>", + expr.get_method_name ().get_segment ().as_string ().c_str ()); + return; + } + + auto candidate = *candidates.begin (); rust_debug_loc (expr.get_method_name ().get_locus (), "resolved method to: {%u} {%s}", candidate.candidate.ty->get_ref (), @@ -1422,14 +1435,28 @@ TypeCheckExpr::resolve_operator_overload ( return false; auto segment = HIR::PathIdentSegment (associated_item_name); - auto candidate + auto candidates = MethodResolver::Probe (lhs, HIR::PathIdentSegment (associated_item_name)); - bool have_implementation_for_lang_item = !candidate.is_error (); + bool have_implementation_for_lang_item = candidates.size () > 0; if (!have_implementation_for_lang_item) return false; + if (candidates.size () > 1) + { + // mutliple candidates + RichLocation r (expr.get_locus ()); + for (auto &c : candidates) + r.add_range (c.candidate.locus); + + rust_error_at ( + r, "multiple candidates found for possible operator overload"); + + return false; + } + // Get the adjusted self + auto candidate = *candidates.begin (); Adjuster adj (lhs); TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments); diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h index d47cbb4369a..5dfd2d7184a 100644 --- a/gcc/rust/typecheck/rust-tyty-cmp.h +++ b/gcc/rust/typecheck/rust-tyty-cmp.h @@ -28,6 +28,10 @@ namespace Rust { namespace TyTy { +// we need to fix this properly by implementing the match for assembling +// candidates +extern bool autoderef_cmp_flag; + class BaseCmp : public TyConstVisitor { public: @@ -1244,6 +1248,9 @@ public: auto other_base_type = type.get_base (); bool mutability_ok = base->is_mutable () ? type.is_mutable () : true; + if (autoderef_cmp_flag) + mutability_ok = base->mutability () == type.mutability (); + if (!mutability_ok) { BaseCmp::visit (type); @@ -1289,9 +1296,10 @@ public: auto base_type = base->get_base (); auto other_base_type = type.get_base (); - // rust is permissive about mutablity here you can always go from mutable to - // immutable but not the otherway round bool mutability_ok = base->is_mutable () ? type.is_mutable () : true; + if (autoderef_cmp_flag) + mutability_ok = base->mutability () == type.mutability (); + if (!mutability_ok) { BaseCmp::visit (type); @@ -1370,7 +1378,7 @@ public: void visit (const ArrayType &) override { ok = true; } - void visit (const SliceType &) override { ok = true; } + void visit (const SliceType &) override { ok = !autoderef_cmp_flag; } void visit (const BoolType &) override { ok = true; } diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index e2f79971337..462c5bf91fd 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -32,6 +32,19 @@ namespace Rust { namespace TyTy { +bool autoderef_cmp_flag = false; + +void +set_cmp_autoderef_mode () +{ + autoderef_cmp_flag = true; +} +void +reset_cmp_autoderef_mode () +{ + autoderef_cmp_flag = false; +} + std::string TypeKindFormat::to_string (TypeKind kind) { diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index a033fcad6c9..b17f01f67ea 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -135,6 +135,11 @@ protected: std::vector specified_bounds; }; +extern void +set_cmp_autoderef_mode (); +extern void +reset_cmp_autoderef_mode (); + class TyVisitor; class TyConstVisitor; class BaseType : public TypeBoundsMappings diff --git a/gcc/testsuite/rust/compile/generics7.rs b/gcc/testsuite/rust/compile/generics7.rs index 2a41632e693..2789c30ee38 100644 --- a/gcc/testsuite/rust/compile/generics7.rs +++ b/gcc/testsuite/rust/compile/generics7.rs @@ -3,13 +3,13 @@ struct Foo { } impl Foo { - fn bar(self) -> isize { // { dg-error "duplicate definitions with name bar" } + fn bar(self) -> isize { self.a } } impl Foo { - fn bar(self) -> char { // { dg-error "duplicate definitions with name bar" } + fn bar(self) -> char { self.a } } @@ -23,4 +23,6 @@ impl Foo { fn main() { let a = Foo { a: 123 }; a.bar(); + // { dg-error "multiple candidates found for method .bar." "" { target *-*-* } .-1 } + // { dg-error "failed to type resolve expression" "" { target *-*-* } .-2 } } diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_9.rs b/gcc/testsuite/rust/execute/torture/operator_overload_9.rs index fbb96a60d36..fd972e28ab3 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 "imm_deref\n123\n" } */ +/* { dg-output "mut_deref\n123\n" } */ extern "C" { fn printf(s: *const i8, ...); }