From patchwork Wed Apr 5 14:02:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arthur Cohen X-Patchwork-Id: 67318 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D1296395C04B for ; Wed, 5 Apr 2023 14:08:20 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by sourceware.org (Postfix) with ESMTPS id 1428C385B508 for ; Wed, 5 Apr 2023 14:05:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1428C385B508 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-x333.google.com with SMTP id d11-20020a05600c3acb00b003ef6e6754c5so18371020wms.5 for ; Wed, 05 Apr 2023 07:05:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; t=1680703533; 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=Tp6SnEuHWm8vBC5WmWyH9Q6wIVWfD7BEbVqFTHjuXu8=; b=TmzmDLm6ldVoO3KNG/59/iOmAKB2RrNYOYXNGKcoQHV/TjWHKYLmO8eBUyASQ7U4v3 ZsEJ89sE/9UK+gHGrc3h8GlzPfsSjhxc9ifXJDRVjLaPmwGJP7PA7Vr5Bw63rVjrCpku ELD5nV/VkLCKGycjvoqEpsqZZlMu1FRs7hKGEqM2uBxLz1W1wDKbmAiwEVhgzViPjTFp aLlNXV9E6QTG5sv3Jm4A0q+LRcyyGbwvsPF5V/NBZWYBXH7jwELCoC7vpPQB3sTzIzwi Bxf2o7sFcCqRjRQJ0Hs/EwpGcT1wCsv+3iU9rl7EGU6RCCAnDLSD3h/6nFpBydLiGwAQ aXwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680703533; 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=Tp6SnEuHWm8vBC5WmWyH9Q6wIVWfD7BEbVqFTHjuXu8=; b=BD2ElAP7g0MyGVv3jBVeBvDrt4RkoglkYeQkLxj29jRHD14zckEiP4yBMgkwltzpHL KTf2QZ+k6xqa+hWPUG3hgzI/Bx1Hg1CQfx57aa/knKHZE3WT5Yfk55RAl1XO9/s+vVBY WzeNaJV1wZsOn6HlVUV/VBf+vjqGPoqwSdTqRG6Uh5Hb5IRA6yYe/cp1Jq3IFNfYzM60 9W1THdDGCkjcgHB+YzCNJLJJycnmkgLPC1NfaEIhyec3NzU5Q2dx/P9M91SfkbG/ezPI Cxt9nqekUP95bGPoZ/WAWEyQgAWnYmN8wbNEGZOdayMR341sYyMmyJCOWTGIqUF5Usu1 w5rQ== X-Gm-Message-State: AAQBX9fTolizvDitcvvv9oPLJUluPB5QqwYRLsudzqzqB2Rk65mcwA8T FTyWY8gkeQyUmD0ztwb9V7lQ4W6sK6kEpja4+g== X-Google-Smtp-Source: AKy350YRrGtJANDnFHDVE6lVsVwGoHpoN63hDIJPyDsoRR/3lVa1DGmN3YCbi2VG6sxjQwT/srWqew== X-Received: by 2002:a05:600c:1f06:b0:3f0:5ed7:f859 with SMTP id bd6-20020a05600c1f0600b003f05ed7f859mr2005497wmb.7.1680703533099; Wed, 05 Apr 2023 07:05:33 -0700 (PDT) Received: from platypus.localdomain ([62.23.166.218]) by smtp.gmail.com with ESMTPSA id ay8-20020a05600c1e0800b003edddae1068sm2330150wmb.9.2023.04.05.07.05.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Apr 2023 07:05:32 -0700 (PDT) From: arthur.cohen@embecosm.com To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Philip Herron Subject: [committed 07/88] gccrs: Support associated type bound arguments Date: Wed, 5 Apr 2023 16:02:51 +0200 Message-Id: <20230405140411.3016563-8-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230405140411.3016563-1-arthur.cohen@embecosm.com> References: <20230405140411.3016563-1-arthur.cohen@embecosm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-14.6 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=ham 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Philip Herron This patch adds support for the GenercArgsBinding type, where you can specify the associated types of a trait bound using `` style syntax. Note that the type-resolution relys on the i32 impl for Add as type resolution will resolve the `a+a` to the core::ops::Add method so code generation will require this to exist. I have ameded testsuite/rust/compile/bounds.rs as this code is wrongly creating an HIR::GenericArgs with a trait-object type and causing issues. the parsing is still correct but we dont have the mechanism to represent this in AST and HIR properly. I think we will need a new HIR::GenericArgs AssociatedTypeBindingBound or something similar. We are still lacking bounds checking during are type coercions and unifications so running this example using an f32 will wrongly pass type checking, this will need addressed next. Fixes #1720 gcc/rust/ChangeLog: * hir/tree/rust-hir-path.h: Add const get_identifier and get_type method. * typecheck/rust-hir-path-probe.h: Use new SubstitutionArgumentMappings constructor. * typecheck/rust-hir-trait-resolve.cc: Likewise. * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise. * typecheck/rust-tyty-bounds.cc (TypeCheckBase::get_predicate_from_bound): Do not assert failure on size mismatch anymore. (TypeBoundPredicate::TypeBoundPredicate): Use new SubstitutionArgumentMappings constructor. (TypeBoundPredicate::operator=): Likewise. (TypeBoundPredicate::apply_generic_arguments): Likewise. (TypeBoundPredicateItem::get_tyty_for_receiver): Likewise. (TypeBoundPredicate::get_num_associated_bindings): Likewise. (TypeBoundPredicate::lookup_associated_type): Fix implementation for new system. (TypeBoundPredicate::get_associated_type_items): Likewise. * typecheck/rust-tyty.cc (SubstitutionRef::get_mappings_from_generic_args): Add new behavior. (SubstitutionRef::infer_substitions): Use new constructor and add comment. (SubstitutionRef::solve_missing_mappings_from_this): Use new constructor. * typecheck/rust-tyty.h: Define new constructors. gcc/testsuite/ChangeLog: * rust/compile/bounds.rs: change to use -fsyntax-only * rust/execute/torture/issue-1720.rs: New test. Signed-off-by: Philip Herron --- gcc/rust/hir/tree/rust-hir-path.h | 4 +- gcc/rust/typecheck/rust-hir-path-probe.h | 3 +- gcc/rust/typecheck/rust-hir-trait-resolve.cc | 11 +-- .../typecheck/rust-hir-type-check-expr.cc | 12 ++- gcc/rust/typecheck/rust-tyty-bounds.cc | 89 ++++++++++++++++--- gcc/rust/typecheck/rust-tyty.cc | 73 +++++++++++++-- gcc/rust/typecheck/rust-tyty.h | 48 ++++++++-- gcc/testsuite/rust/compile/bounds.rs | 8 +- .../rust/execute/torture/issue-1720.rs | 26 ++++++ 9 files changed, 236 insertions(+), 38 deletions(-) create mode 100644 gcc/testsuite/rust/execute/torture/issue-1720.rs diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h index 17eedb8d741..740de9391a0 100644 --- a/gcc/rust/hir/tree/rust-hir-path.h +++ b/gcc/rust/hir/tree/rust-hir-path.h @@ -105,9 +105,11 @@ public: std::string as_string () const; - Identifier get_identifier () const { return identifier; } + Identifier &get_identifier () { return identifier; } + const Identifier &get_identifier () const { return identifier; } std::unique_ptr &get_type () { return type; } + const std::unique_ptr &get_type () const { return type; } Location get_locus () const { return locus; } }; diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h index 6d6bcf8e7cd..bb8698ce0e1 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.h +++ b/gcc/rust/typecheck/rust-hir-path-probe.h @@ -362,7 +362,8 @@ protected: mappings.push_back (TyTy::SubstitutionArg (param, receiver->clone ())); Location locus; // FIXME - TyTy::SubstitutionArgumentMappings args (std::move (mappings), locus); + TyTy::SubstitutionArgumentMappings args (std::move (mappings), {}, + locus); trait_item_tyty = SubstMapperInternal::Resolve (trait_item_tyty, args); } diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index 2ec9b2ef83e..85cad8e9c21 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc @@ -441,8 +441,8 @@ AssociatedImplTrait::setup_associated_types ( param_mappings[p.get_symbol ()] = a.get_tyty ()->get_ref (); }; - TyTy::SubstitutionArgumentMappings infer_arguments (std::move (args), locus, - param_subst_cb); + TyTy::SubstitutionArgumentMappings infer_arguments (std::move (args), {}, + locus, param_subst_cb); TyTy::BaseType *impl_self_infer = (associated_self->needs_generic_substitutions ()) ? SubstMapperInternal::Resolve (associated_self, infer_arguments) @@ -489,8 +489,9 @@ AssociatedImplTrait::setup_associated_types ( hrtb_bound_arguments.push_back (r); } - rust_assert (impl_trait_predicate_args.size () - == hrtb_bound_arguments.size ()); + if (impl_trait_predicate_args.size () != hrtb_bound_arguments.size ()) + return; + for (size_t i = 0; i < impl_trait_predicate_args.size (); i++) { TyTy::BaseType *a = impl_trait_predicate_args.at (i); @@ -521,7 +522,7 @@ AssociatedImplTrait::setup_associated_types ( } TyTy::SubstitutionArgumentMappings associated_type_args ( - std::move (associated_arguments), locus); + std::move (associated_arguments), {}, locus); ImplTypeIterator iter (*impl, [&] (HIR::TypeAlias &type) { TraitItemReference *resolved_trait_item = nullptr; diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index 5c43cc8c7b4..46a14eb6e92 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -618,7 +618,8 @@ TypeCheckExpr::visit (HIR::RangeFromToExpr &expr) const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0); subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, unified)); - TyTy::SubstitutionArgumentMappings subst (subst_mappings, expr.get_locus ()); + TyTy::SubstitutionArgumentMappings subst (subst_mappings, {}, + expr.get_locus ()); infered = SubstMapperInternal::Resolve (adt, subst); } @@ -664,7 +665,8 @@ TypeCheckExpr::visit (HIR::RangeFromExpr &expr) const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0); subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, from_ty)); - TyTy::SubstitutionArgumentMappings subst (subst_mappings, expr.get_locus ()); + TyTy::SubstitutionArgumentMappings subst (subst_mappings, {}, + expr.get_locus ()); infered = SubstMapperInternal::Resolve (adt, subst); } @@ -709,7 +711,8 @@ TypeCheckExpr::visit (HIR::RangeToExpr &expr) const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0); subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, from_ty)); - TyTy::SubstitutionArgumentMappings subst (subst_mappings, expr.get_locus ()); + TyTy::SubstitutionArgumentMappings subst (subst_mappings, {}, + expr.get_locus ()); infered = SubstMapperInternal::Resolve (adt, subst); } @@ -792,7 +795,8 @@ TypeCheckExpr::visit (HIR::RangeFromToInclExpr &expr) const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0); subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, unified)); - TyTy::SubstitutionArgumentMappings subst (subst_mappings, expr.get_locus ()); + TyTy::SubstitutionArgumentMappings subst (subst_mappings, {}, + expr.get_locus ()); infered = SubstMapperInternal::Resolve (adt, subst); } diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc index 20a81ada6c4..30f7b0d02e3 100644 --- a/gcc/rust/typecheck/rust-tyty-bounds.cc +++ b/gcc/rust/typecheck/rust-tyty-bounds.cc @@ -145,11 +145,10 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path) break; } - // FIXME - // I think this should really be just be if the !args.is_empty() because - // someone might wrongly apply generic arguments where they should not and - // they will be missing error diagnostics - if (predicate.requires_generic_args ()) + // we try to apply generic arguments when they are non empty and or when the + // predicate requires them so that we get the relevant Foo expects x number + // arguments but got zero see test case rust/compile/traits12.rs + if (!args.is_empty () || predicate.requires_generic_args ()) { // this is applying generic arguments to a trait reference predicate.apply_generic_arguments (&args); @@ -222,7 +221,7 @@ TypeBoundPredicate::TypeBoundPredicate (const TypeBoundPredicate &other) } used_arguments - = SubstitutionArgumentMappings (copied_arg_mappings, + = SubstitutionArgumentMappings (copied_arg_mappings, {}, other.used_arguments.get_locus ()); } @@ -258,7 +257,7 @@ TypeBoundPredicate::operator= (const TypeBoundPredicate &other) } used_arguments - = SubstitutionArgumentMappings (copied_arg_mappings, + = SubstitutionArgumentMappings (copied_arg_mappings, {}, other.used_arguments.get_locus ()); return *this; @@ -331,6 +330,19 @@ TypeBoundPredicate::apply_generic_arguments (HIR::GenericArgs *generic_args) if (ok && arg.get_tyty () != nullptr) sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ()); } + + // associated argument mappings + for (auto &it : subst_mappings.get_binding_args ()) + { + std::string identifier = it.first; + TyTy::BaseType *type = it.second; + + TypeBoundPredicateItem item = lookup_associated_item (identifier); + rust_assert (!item.is_error ()); + + const auto item_ref = item.get_raw_item (); + item_ref->associated_type_set (type); + } } bool @@ -389,7 +401,8 @@ TypeBoundPredicateItem::get_tyty_for_receiver (const TyTy::BaseType *receiver) adjusted_mappings.push_back (std::move (arg)); } - SubstitutionArgumentMappings adjusted (adjusted_mappings, gargs.get_locus (), + SubstitutionArgumentMappings adjusted (adjusted_mappings, {}, + gargs.get_locus (), gargs.get_subst_cb (), true /* trait-mode-flag */); return Resolver::SubstMapperInternal::Resolve (trait_item_tyty, adjusted); @@ -421,6 +434,19 @@ TypeBoundPredicate::handle_substitions ( p->set_ty_ref (s->get_ty_ref ()); } + // associated argument mappings + for (auto &it : subst_mappings.get_binding_args ()) + { + std::string identifier = it.first; + TyTy::BaseType *type = it.second; + + TypeBoundPredicateItem item = lookup_associated_item (identifier); + rust_assert (!item.is_error ()); + + const auto item_ref = item.get_raw_item (); + item_ref->associated_type_set (type); + } + // FIXME more error handling at some point // used_arguments = subst_mappings; // error_flag |= used_arguments.is_error (); @@ -440,6 +466,13 @@ TypeBoundPredicate::requires_generic_args () const bool TypeBoundPredicate::contains_associated_types () const { + return get_num_associated_bindings () > 0; +} + +size_t +TypeBoundPredicate::get_num_associated_bindings () const +{ + size_t count = 0; auto trait_ref = get (); for (const auto &trait_item : trait_ref->get_trait_items ()) { @@ -447,9 +480,45 @@ TypeBoundPredicate::contains_associated_types () const = trait_item.get_trait_item_type () == Resolver::TraitItemReference::TraitItemType::TYPE; if (is_associated_type) - return true; + count++; + } + return count; +} + +TypeBoundPredicateItem +TypeBoundPredicate::lookup_associated_type (const std::string &search) +{ + TypeBoundPredicateItem item = lookup_associated_item (search); + + // only need to check that it is infact an associated type because other wise + // if it was not found it will just be an error node anyway + if (!item.is_error ()) + { + const auto raw = item.get_raw_item (); + if (raw->get_trait_item_type () + != Resolver::TraitItemReference::TraitItemType::TYPE) + return TypeBoundPredicateItem::error (); + } + return item; +} + +std::vector +TypeBoundPredicate::get_associated_type_items () +{ + std::vector items; + auto trait_ref = get (); + for (const auto &trait_item : trait_ref->get_trait_items ()) + { + bool is_associated_type + = trait_item.get_trait_item_type () + == Resolver::TraitItemReference::TraitItemType::TYPE; + if (is_associated_type) + { + TypeBoundPredicateItem item (this, &trait_item); + items.push_back (std::move (item)); + } } - return false; + return items; } // trait item reference diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 71f0de1bbab..fd57a534562 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -674,14 +674,58 @@ SubstitutionParamMapping::override_context () SubstitutionArgumentMappings SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args) { + std::map binding_arguments; if (args.get_binding_args ().size () > 0) { - RichLocation r (args.get_locus ()); - for (auto &binding : args.get_binding_args ()) - r.add_range (binding.get_locus ()); + if (supports_associated_bindings ()) + { + if (args.get_binding_args ().size () > get_num_associated_bindings ()) + { + RichLocation r (args.get_locus ()); + + rust_error_at (r, + "generic item takes at most %lu type binding " + "arguments but %lu were supplied", + (unsigned long) get_num_associated_bindings (), + (unsigned long) args.get_binding_args ().size ()); + return SubstitutionArgumentMappings::error (); + } - rust_error_at (r, "associated type bindings are not allowed here"); - return SubstitutionArgumentMappings::error (); + for (auto &binding : args.get_binding_args ()) + { + BaseType *resolved + = Resolver::TypeCheckType::Resolve (binding.get_type ().get ()); + if (resolved == nullptr + || resolved->get_kind () == TyTy::TypeKind::ERROR) + { + rust_error_at (binding.get_locus (), + "failed to resolve type arguments"); + return SubstitutionArgumentMappings::error (); + } + + // resolve to relevant binding + auto binding_item + = lookup_associated_type (binding.get_identifier ()); + if (binding_item.is_error ()) + { + rust_error_at (binding.get_locus (), + "unknown associated type binding: %s", + binding.get_identifier ().c_str ()); + return SubstitutionArgumentMappings::error (); + } + + binding_arguments[binding.get_identifier ()] = resolved; + } + } + else + { + RichLocation r (args.get_locus ()); + for (auto &binding : args.get_binding_args ()) + r.add_range (binding.get_locus ()); + + rust_error_at (r, "associated type bindings are not allowed here"); + return SubstitutionArgumentMappings::error (); + } } // for inherited arguments @@ -745,6 +789,7 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args) if (resolved->contains_type_parameters ()) { SubstitutionArgumentMappings intermediate (mappings, + binding_arguments, args.get_locus ()); resolved = Resolver::SubstMapperInternal::Resolve (resolved, intermediate); @@ -758,7 +803,8 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args) } } - return SubstitutionArgumentMappings (mappings, args.get_locus ()); + return SubstitutionArgumentMappings (mappings, binding_arguments, + args.get_locus ()); } BaseType * @@ -791,7 +837,13 @@ SubstitutionRef::infer_substitions (Location locus) } } - SubstitutionArgumentMappings infer_arguments (std::move (args), locus); + // FIXME do we need to add inference variables to all the possible bindings? + // it might just lead to inference variable hell not 100% sure if rustc does + // this i think the language might needs this to be explicitly set + + SubstitutionArgumentMappings infer_arguments (std::move (args), + {} /* binding_arguments */, + locus); return handle_substitions (std::move (infer_arguments)); } @@ -835,7 +887,9 @@ SubstitutionRef::adjust_mappings_for_this ( if (resolved_mappings.empty ()) return SubstitutionArgumentMappings::error (); - return SubstitutionArgumentMappings (resolved_mappings, mappings.get_locus (), + return SubstitutionArgumentMappings (resolved_mappings, + mappings.get_binding_args (), + mappings.get_locus (), mappings.get_subst_cb (), mappings.trait_item_mode ()); } @@ -901,6 +955,7 @@ SubstitutionRef::solve_mappings_from_receiver_for_self ( } return SubstitutionArgumentMappings (resolved_mappings, + mappings.get_binding_args (), mappings.get_locus ()); } @@ -952,7 +1007,7 @@ SubstitutionRef::solve_missing_mappings_from_this (SubstitutionRef &ref, resolved_mappings.push_back (std::move (argument)); } - return SubstitutionArgumentMappings (resolved_mappings, locus); + return SubstitutionArgumentMappings (resolved_mappings, {}, locus); } bool diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 0fd664c8d46..20a243fe980 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -675,16 +675,17 @@ class SubstitutionArgumentMappings { public: SubstitutionArgumentMappings (std::vector mappings, + std::map binding_args, Location locus, ParamSubstCb param_subst_cb = nullptr, bool trait_item_flag = false) - : mappings (mappings), locus (locus), param_subst_cb (param_subst_cb), - trait_item_flag (trait_item_flag) + : mappings (mappings), binding_args (binding_args), locus (locus), + param_subst_cb (param_subst_cb), trait_item_flag (trait_item_flag) {} SubstitutionArgumentMappings (const SubstitutionArgumentMappings &other) - : mappings (other.mappings), locus (other.locus), - param_subst_cb (other.param_subst_cb), + : mappings (other.mappings), binding_args (other.binding_args), + locus (other.locus), param_subst_cb (other.param_subst_cb), trait_item_flag (other.trait_item_flag) {} @@ -692,6 +693,7 @@ public: operator= (const SubstitutionArgumentMappings &other) { mappings = other.mappings; + binding_args = other.binding_args; locus = other.locus; param_subst_cb = other.param_subst_cb; trait_item_flag = other.trait_item_flag; @@ -705,7 +707,7 @@ public: static SubstitutionArgumentMappings error () { - return SubstitutionArgumentMappings ({}, Location (), nullptr, false); + return SubstitutionArgumentMappings ({}, {}, Location (), nullptr, false); } bool is_error () const { return mappings.size () == 0; } @@ -759,6 +761,16 @@ public: const std::vector &get_mappings () const { return mappings; } + std::map &get_binding_args () + { + return binding_args; + } + + const std::map &get_binding_args () const + { + return binding_args; + } + std::string as_string () const { std::string buffer; @@ -783,6 +795,7 @@ public: private: std::vector mappings; + std::map binding_args; Location locus; ParamSubstCb param_subst_cb; bool trait_item_flag; @@ -813,6 +826,24 @@ public: return buffer.empty () ? "" : "<" + buffer + ">"; } + bool supports_associated_bindings () const + { + return get_num_associated_bindings () > 0; + } + + // this is overridden in TypeBoundPredicate + // which support bindings we don't add them directly to the SubstitutionRef + // base class because this class represents the fn. The only + // construct which supports associated types + virtual size_t get_num_associated_bindings () const { return 0; } + + // this is overridden in TypeBoundPredicate + virtual TypeBoundPredicateItem + lookup_associated_type (const std::string &search) + { + return TypeBoundPredicateItem::error (); + } + size_t get_num_substitutions () const { return substitutions.size (); } std::vector &get_substs () { return substitutions; } @@ -1040,6 +1071,13 @@ public: DefId get_id () const { return reference; } + std::vector get_associated_type_items (); + + size_t get_num_associated_bindings () const override final; + + TypeBoundPredicateItem + lookup_associated_type (const std::string &search) override final; + private: DefId reference; Location locus; diff --git a/gcc/testsuite/rust/compile/bounds.rs b/gcc/testsuite/rust/compile/bounds.rs index ecb10d81f65..57ff17ffcdc 100644 --- a/gcc/testsuite/rust/compile/bounds.rs +++ b/gcc/testsuite/rust/compile/bounds.rs @@ -1,10 +1,12 @@ +// { dg-options "-fsyntax-only" } trait Foo { type Bar; } trait Copy {} - -fn c>() where F::Bar: Copy { // { dg-warning "function is never used: 'c'" } +fn c>() +where + F::Bar: Copy, +{ } - diff --git a/gcc/testsuite/rust/execute/torture/issue-1720.rs b/gcc/testsuite/rust/execute/torture/issue-1720.rs new file mode 100644 index 00000000000..771d7eec537 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-1720.rs @@ -0,0 +1,26 @@ +mod core { + mod ops { + #[lang = "add"] + pub trait Add { + type Output; + + fn add(self, rhs: Rhs) -> Self::Output; + } + } +} + +impl core::ops::Add for i32 { + type Output = i32; + + fn add(self, rhs: i32) -> Self::Output { + self + rhs + } +} + +pub fn foo>(a: T) -> i32 { + a + a +} + +pub fn main() -> i32 { + foo(1) - 2 +}