diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-ref.h | 22 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-resolve.cc | 4 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-implitem.h | 160 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-item.h | 10 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.h | 4 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-substitution-mapper.h | 9 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-bounds.cc | 86 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 18 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 28 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/traits9.rs | 3 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/issue-1120.rs | 123 |
11 files changed, 332 insertions, 135 deletions
diff --git a/gcc/rust/typecheck/rust-hir-trait-ref.h b/gcc/rust/typecheck/rust-hir-trait-ref.h index d8c8a19..a12736f 100644 --- a/gcc/rust/typecheck/rust-hir-trait-ref.h +++ b/gcc/rust/typecheck/rust-hir-trait-ref.h @@ -137,9 +137,9 @@ public: // the trait will not be stored in its own map yet void on_resolved (); - void associated_type_set (TyTy::BaseType *ty); + void associated_type_set (TyTy::BaseType *ty) const; - void associated_type_reset (); + void associated_type_reset () const; bool is_object_safe () const; @@ -301,6 +301,24 @@ public: return false; } + bool lookup_trait_item_by_type (const std::string &ident, + TraitItemReference::TraitItemType type, + const TraitItemReference **ref) const + { + for (auto &item : item_refs) + { + if (item.get_trait_item_type () != type) + continue; + + if (ident.compare (item.get_identifier ()) == 0) + { + *ref = &item; + return true; + } + } + return false; + } + bool lookup_hir_trait_item (const HIR::TraitItem &item, const TraitItemReference **ref) const { diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index b4e0efe..5681ebd 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc @@ -128,7 +128,7 @@ TraitItemReference::resolve_item (HIR::TraitItemFunc &func) } void -TraitItemReference::associated_type_set (TyTy::BaseType *ty) +TraitItemReference::associated_type_set (TyTy::BaseType *ty) const { rust_assert (get_trait_item_type () == TraitItemType::TYPE); @@ -141,7 +141,7 @@ TraitItemReference::associated_type_set (TyTy::BaseType *ty) } void -TraitItemReference::associated_type_reset () +TraitItemReference::associated_type_reset () const { rust_assert (get_trait_item_type () == TraitItemType::TYPE); diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h index f1b5e35..52c866c 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h +++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h @@ -385,9 +385,9 @@ class TypeCheckImplItemWithTrait : public TypeCheckImplItem using Rust::Resolver::TypeCheckBase::visit; public: - static const TraitItemReference * + static TyTy::TypeBoundPredicateItem Resolve (HIR::ImplBlock *parent, HIR::ImplItem *item, TyTy::BaseType *self, - TraitReference &trait_reference, + TyTy::TypeBoundPredicate &trait_reference, std::vector<TyTy::SubstitutionParamMapping> substitutions) { TypeCheckImplItemWithTrait resolver (parent, self, trait_reference, @@ -398,38 +398,46 @@ public: void visit (HIR::ConstantItem &constant) override { - trait_reference.lookup_trait_item_by_type ( + // normal resolution of the item + TypeCheckImplItem::visit (constant); + TyTy::BaseType *lookup; + if (!context->lookup_type (constant.get_mappings ().get_hirid (), &lookup)) + return; + + // map the impl item to the associated trait item + const auto tref = trait_reference.get (); + const TraitItemReference *raw_trait_item = nullptr; + bool found = tref->lookup_trait_item_by_type ( constant.get_identifier (), TraitItemReference::TraitItemType::CONST, - &resolved_trait_item); + &raw_trait_item); // unknown trait item - if (resolved_trait_item->is_error ()) + if (!found || raw_trait_item->is_error ()) { RichLocation r (constant.get_locus ()); r.add_range (trait_reference.get_locus ()); rust_error_at (r, "constant %<%s%> is not a member of trait %<%s%>", constant.get_identifier ().c_str (), trait_reference.get_name ().c_str ()); + return; } - // normal resolution of the item - TypeCheckImplItem::visit (constant); - TyTy::BaseType *lookup; - if (!context->lookup_type (constant.get_mappings ().get_hirid (), &lookup)) - return; - if (resolved_trait_item->is_error ()) - return; + // get the item from the predicate + resolved_trait_item + = trait_reference.lookup_associated_item (raw_trait_item); + rust_assert (!resolved_trait_item.is_error ()); // merge the attributes const HIR::TraitItem *hir_trait_item - = resolved_trait_item->get_hir_trait_item (); + = resolved_trait_item.get_raw_item ()->get_hir_trait_item (); merge_attributes (constant.get_outer_attrs (), *hir_trait_item); // check the types are compatible - if (!resolved_trait_item->get_tyty ()->can_eq (lookup, true)) + auto trait_item_type = resolved_trait_item.get_tyty_for_receiver (self); + if (!trait_item_type->can_eq (lookup, true)) { RichLocation r (constant.get_locus ()); - r.add_range (resolved_trait_item->get_locus ()); + r.add_range (resolved_trait_item.get_locus ()); rust_error_at ( r, "constant %<%s%> has an incompatible type for trait %<%s%>", @@ -440,38 +448,46 @@ public: void visit (HIR::TypeAlias &type) override { - trait_reference.lookup_trait_item_by_type ( + // normal resolution of the item + TypeCheckImplItem::visit (type); + TyTy::BaseType *lookup; + if (!context->lookup_type (type.get_mappings ().get_hirid (), &lookup)) + return; + + // map the impl item to the associated trait item + const auto tref = trait_reference.get (); + const TraitItemReference *raw_trait_item = nullptr; + bool found = tref->lookup_trait_item_by_type ( type.get_new_type_name (), TraitItemReference::TraitItemType::TYPE, - &resolved_trait_item); + &raw_trait_item); // unknown trait item - if (resolved_trait_item->is_error ()) + if (!found || raw_trait_item->is_error ()) { RichLocation r (type.get_locus ()); r.add_range (trait_reference.get_locus ()); rust_error_at (r, "type alias %<%s%> is not a member of trait %<%s%>", type.get_new_type_name ().c_str (), trait_reference.get_name ().c_str ()); + return; } - // normal resolution of the item - TypeCheckImplItem::visit (type); - TyTy::BaseType *lookup; - if (!context->lookup_type (type.get_mappings ().get_hirid (), &lookup)) - return; - if (resolved_trait_item->is_error ()) - return; + // get the item from the predicate + resolved_trait_item + = trait_reference.lookup_associated_item (raw_trait_item); + rust_assert (!resolved_trait_item.is_error ()); // merge the attributes const HIR::TraitItem *hir_trait_item - = resolved_trait_item->get_hir_trait_item (); + = resolved_trait_item.get_raw_item ()->get_hir_trait_item (); merge_attributes (type.get_outer_attrs (), *hir_trait_item); // check the types are compatible - if (!resolved_trait_item->get_tyty ()->can_eq (lookup, true)) + auto trait_item_type = resolved_trait_item.get_tyty_for_receiver (self); + if (!trait_item_type->can_eq (lookup, true)) { RichLocation r (type.get_locus ()); - r.add_range (resolved_trait_item->get_locus ()); + r.add_range (resolved_trait_item.get_locus ()); rust_error_at ( r, "type alias %<%s%> has an incompatible type for trait %<%s%>", @@ -481,83 +497,63 @@ public: // its actually a projection, since we need a way to actually bind the // generic substitutions to the type itself - TyTy::ProjectionType *projection = new TyTy::ProjectionType ( - type.get_mappings ().get_hirid (), lookup, &trait_reference, - resolved_trait_item->get_mappings ().get_defid (), substitutions); + TyTy::ProjectionType *projection + = new TyTy::ProjectionType (type.get_mappings ().get_hirid (), lookup, + tref, + raw_trait_item->get_mappings ().get_defid (), + substitutions); context->insert_type (type.get_mappings (), projection); - resolved_trait_item->associated_type_set (projection); + raw_trait_item->associated_type_set (projection); } void visit (HIR::Function &function) override { - // resolved_trait_item = trait_reference.lookup_trait_item ( - // function.get_function_name (), TraitItemReference::TraitItemType::FN); - trait_reference.lookup_trait_item_by_type ( - function.get_function_name (), TraitItemReference::TraitItemType::FN, - &resolved_trait_item); + // we get the error checking from the base method here + TypeCheckImplItem::visit (function); + TyTy::BaseType *lookup; + if (!context->lookup_type (function.get_mappings ().get_hirid (), &lookup)) + return; + + // map the impl item to the associated trait item + const auto tref = trait_reference.get (); + const TraitItemReference *raw_trait_item = nullptr; + bool found + = tref->lookup_trait_item_by_type (function.get_function_name (), + TraitItemReference::TraitItemType::FN, + &raw_trait_item); // unknown trait item - if (resolved_trait_item->is_error ()) + if (!found || raw_trait_item->is_error ()) { RichLocation r (function.get_locus ()); r.add_range (trait_reference.get_locus ()); rust_error_at (r, "method %<%s%> is not a member of trait %<%s%>", function.get_function_name ().c_str (), trait_reference.get_name ().c_str ()); + return; } - // we get the error checking from the base method here - TypeCheckImplItem::visit (function); - TyTy::BaseType *lookup; - if (!context->lookup_type (function.get_mappings ().get_hirid (), &lookup)) - return; - if (resolved_trait_item->is_error ()) - return; + // get the item from the predicate + resolved_trait_item + = trait_reference.lookup_associated_item (raw_trait_item); + rust_assert (!resolved_trait_item.is_error ()); // merge the attributes const HIR::TraitItem *hir_trait_item - = resolved_trait_item->get_hir_trait_item (); + = resolved_trait_item.get_raw_item ()->get_hir_trait_item (); merge_attributes (function.get_outer_attrs (), *hir_trait_item); - rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF); - rust_assert (resolved_trait_item->get_tyty ()->get_kind () - == TyTy::TypeKind::FNDEF); - - TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup); - TyTy::FnType *trait_item_fntype - = static_cast<TyTy::FnType *> (resolved_trait_item->get_tyty ()); - - // sets substitute self into the trait_item_ref->tyty - TyTy::SubstitutionParamMapping *self_mapping = nullptr; - for (auto ¶m_mapping : trait_item_fntype->get_substs ()) - { - const HIR::TypeParam &type_param = param_mapping.get_generic_param (); - if (type_param.get_type_representation ().compare ("Self") == 0) - { - self_mapping = ¶m_mapping; - break; - } - } - rust_assert (self_mapping != nullptr); - - std::vector<TyTy::SubstitutionArg> mappings; - mappings.push_back (TyTy::SubstitutionArg (self_mapping, self)); - - TyTy::SubstitutionArgumentMappings implicit_self_substs ( - mappings, function.get_locus ()); - trait_item_fntype - = trait_item_fntype->handle_substitions (implicit_self_substs); - // check the types are compatible - if (!trait_item_fntype->can_eq (fntype, true)) + auto trait_item_type = resolved_trait_item.get_tyty_for_receiver (self); + if (!trait_item_type->can_eq (lookup, true)) { RichLocation r (function.get_locus ()); - r.add_range (resolved_trait_item->get_locus ()); + r.add_range (resolved_trait_item.get_locus ()); rust_error_at ( r, "method %<%s%> has an incompatible type for trait %<%s%>", - fntype->get_identifier ().c_str (), + function.get_function_name ().c_str (), trait_reference.get_name ().c_str ()); } } @@ -577,10 +573,10 @@ protected: private: TypeCheckImplItemWithTrait ( HIR::ImplBlock *parent, TyTy::BaseType *self, - TraitReference &trait_reference, + TyTy::TypeBoundPredicate &trait_reference, std::vector<TyTy::SubstitutionParamMapping> substitutions) : TypeCheckImplItem (parent, self), trait_reference (trait_reference), - resolved_trait_item (&TraitItemReference::error_node ()), + resolved_trait_item (TyTy::TypeBoundPredicateItem::error ()), substitutions (substitutions) { rust_assert (is_trait_impl_block ()); @@ -588,8 +584,8 @@ private: bool is_trait_impl_block () const { return !trait_reference.is_error (); } - TraitReference &trait_reference; - TraitItemReference *resolved_trait_item; + TyTy::TypeBoundPredicate &trait_reference; + TyTy::TypeBoundPredicateItem resolved_trait_item; std::vector<TyTy::SubstitutionParamMapping> substitutions; }; diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h index 9846ed6..9d3beae 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-item.h +++ b/gcc/rust/typecheck/rust-hir-type-check-item.h @@ -78,9 +78,9 @@ public: trait_reference = TraitResolver::Resolve (*ref.get ()); rust_assert (!trait_reference->is_error ()); + // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs + // for example specified_bound = get_predicate_from_bound (*ref.get ()); - // FIXME error out maybe? - // if specified_Bound == TyTy::TypeBoundPredicate::error() ? } TyTy::BaseType *self = nullptr; @@ -120,9 +120,9 @@ public: auto trait_item_ref = TypeCheckImplItemWithTrait::Resolve (&impl_block, impl_item.get (), self, - *trait_reference, + specified_bound, substitutions); - trait_item_refs.push_back (trait_item_ref); + trait_item_refs.push_back (trait_item_ref.get_raw_item ()); } } @@ -134,7 +134,7 @@ public: // filter the missing impl_items std::vector<std::reference_wrapper<const TraitItemReference>> missing_trait_items; - for (auto &trait_item_ref : trait_reference->get_trait_items ()) + for (const auto &trait_item_ref : trait_reference->get_trait_items ()) { bool found = false; for (auto implemented_trait_item : trait_item_refs) diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h index e63f8ad..8e33783 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.h +++ b/gcc/rust/typecheck/rust-hir-type-check.h @@ -211,8 +211,8 @@ public: void clear_associated_type_mapping (HirId id) { auto it = associated_type_mappings.find (id); - rust_assert (it != associated_type_mappings.end ()); - associated_type_mappings.erase (it); + if (it != associated_type_mappings.end ()) + associated_type_mappings.erase (it); } // lookup any associated type mappings, the out parameter of mapping is diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h index e12432e..028e10c 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.h +++ b/gcc/rust/typecheck/rust-substitution-mapper.h @@ -208,7 +208,14 @@ public: void visit (TyTy::PlaceholderType &type) override { rust_assert (type.can_resolve ()); - resolved = SubstMapperInternal::Resolve (type.resolve (), mappings); + if (mappings.trait_item_mode ()) + { + resolved = type.resolve (); + } + else + { + resolved = SubstMapperInternal::Resolve (type.resolve (), mappings); + } } void visit (TyTy::ProjectionType &type) override diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc index e226400..bda7a7f 100644 --- a/gcc/rust/typecheck/rust-tyty-bounds.cc +++ b/gcc/rust/typecheck/rust-tyty-bounds.cc @@ -103,23 +103,28 @@ namespace TyTy { TypeBoundPredicate::TypeBoundPredicate ( const Resolver::TraitReference &trait_reference, Location locus) - : SubstitutionRef (trait_reference.get_trait_substs (), - SubstitutionArgumentMappings::error ()), + : SubstitutionRef ({}, SubstitutionArgumentMappings::error ()), reference (trait_reference.get_mappings ().get_defid ()), locus (locus), error_flag (false) { + substitutions.clear (); + for (const auto &p : trait_reference.get_trait_substs ()) + substitutions.push_back (p.clone ()); + // we setup a dummy implict self argument SubstitutionArg placeholder_self (&get_substs ().front (), nullptr); used_arguments.get_mappings ().push_back (placeholder_self); } TypeBoundPredicate::TypeBoundPredicate ( - DefId reference, std::vector<SubstitutionParamMapping> substitutions, - Location locus) - : SubstitutionRef (std::move (substitutions), - SubstitutionArgumentMappings::error ()), + DefId reference, std::vector<SubstitutionParamMapping> subst, Location locus) + : SubstitutionRef ({}, SubstitutionArgumentMappings::error ()), reference (reference), locus (locus), error_flag (false) { + substitutions.clear (); + for (const auto &p : subst) + substitutions.push_back (p.clone ()); + // we setup a dummy implict self argument SubstitutionArg placeholder_self (&get_substs ().front (), nullptr); used_arguments.get_mappings ().push_back (placeholder_self); @@ -131,7 +136,6 @@ TypeBoundPredicate::TypeBoundPredicate (const TypeBoundPredicate &other) error_flag (other.error_flag) { substitutions.clear (); - for (const auto &p : other.get_substs ()) substitutions.push_back (p.clone ()); @@ -143,8 +147,19 @@ TypeBoundPredicate::TypeBoundPredicate (const TypeBoundPredicate &other) mappings.push_back (std::move (arg)); } + // we need to remap the argument mappings based on this copied constructor + std::vector<SubstitutionArg> copied_arg_mappings; + size_t i = 0; + for (const auto &m : other.used_arguments.get_mappings ()) + { + TyTy::BaseType *argument + = m.get_tyty () == nullptr ? nullptr : m.get_tyty ()->clone (); + SubstitutionArg c (&substitutions.at (i++), argument); + copied_arg_mappings.push_back (std::move (c)); + } + used_arguments - = SubstitutionArgumentMappings (mappings, + = SubstitutionArgumentMappings (copied_arg_mappings, other.used_arguments.get_locus ()); } @@ -168,8 +183,19 @@ TypeBoundPredicate::operator= (const TypeBoundPredicate &other) mappings.push_back (std::move (arg)); } + // we need to remap the argument mappings based on this copied constructor + std::vector<SubstitutionArg> copied_arg_mappings; + size_t i = 0; + for (const auto &m : other.used_arguments.get_mappings ()) + { + TyTy::BaseType *argument + = m.get_tyty () == nullptr ? nullptr : m.get_tyty ()->clone (); + SubstitutionArg c (&substitutions.at (i++), argument); + copied_arg_mappings.push_back (std::move (c)); + } + used_arguments - = SubstitutionArgumentMappings (mappings, + = SubstitutionArgumentMappings (copied_arg_mappings, other.used_arguments.get_locus ()); return *this; @@ -204,16 +230,7 @@ TypeBoundPredicate::get () const std::string TypeBoundPredicate::get_name () const { - auto mappings = Analysis::Mappings::get (); - auto trait = get (); - auto nodeid = trait->get_mappings ().get_nodeid (); - - const Resolver::CanonicalPath *p = nullptr; - if (mappings->lookup_canonical_path (mappings->get_current_crate (), nodeid, - &p)) - return p->get (); - - return trait->get_name (); + return get ()->get_name (); } bool @@ -285,15 +302,28 @@ TypeBoundPredicateItem::get_tyty_for_receiver (const TyTy::BaseType *receiver) if (is_associated_type) return trait_item_tyty; - SubstitutionArgumentMappings gargs = parent->get_substitution_arguments (); - // set up the self mapping + SubstitutionArgumentMappings gargs = parent->get_substitution_arguments (); rust_assert (!gargs.is_empty ()); - auto &sarg = gargs.get_mappings ().at (0); - SubstitutionArg self (sarg.get_param_mapping (), receiver->clone ()); - gargs.get_mappings ()[0] = self; - return Resolver::SubstMapperInternal::Resolve (trait_item_tyty, gargs); + // setup the adjusted mappings + std::vector<SubstitutionArg> adjusted_mappings; + for (size_t i = 0; i < gargs.get_mappings ().size (); i++) + { + auto &mapping = gargs.get_mappings ().at (i); + + bool is_implicit_self = i == 0; + TyTy::BaseType *argument + = is_implicit_self ? receiver->clone () : mapping.get_tyty (); + + SubstitutionArg arg (mapping.get_param_mapping (), argument); + adjusted_mappings.push_back (std::move (arg)); + } + + SubstitutionArgumentMappings adjusted (adjusted_mappings, gargs.get_locus (), + gargs.get_subst_cb (), + true /* trait-mode-flag */); + return Resolver::SubstMapperInternal::Resolve (trait_item_tyty, adjusted); } bool TypeBoundPredicate::is_error () const @@ -352,6 +382,12 @@ TypeBoundPredicateItem::needs_implementation () const return !get_raw_item ()->is_optional (); } +Location +TypeBoundPredicateItem::get_locus () const +{ + return get_raw_item ()->get_locus (); +} + // TypeBoundsMappings TypeBoundsMappings::TypeBoundsMappings ( diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 156cc10..d9a4243 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -480,7 +480,7 @@ SubstitutionParamMapping::fill_param_ty ( if (type.get_kind () == TypeKind::PARAM) { - delete param; + // delete param; param = static_cast<ParamType *> (type.clone ()); } else @@ -643,8 +643,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_locus (), + mappings.get_subst_cb (), + mappings.trait_item_mode ()); } bool @@ -2699,6 +2700,13 @@ ProjectionType::clone () const ProjectionType * ProjectionType::handle_substitions (SubstitutionArgumentMappings subst_mappings) { + // // do we really need to substitute this? + // if (base->needs_generic_substitutions () || base->contains_type_parameters + // ()) + // { + // return this; + // } + ProjectionType *projection = static_cast<ProjectionType *> (clone ()); projection->set_ty_ref (mappings->get_next_hir_id ()); projection->used_arguments = subst_mappings; @@ -2755,9 +2763,7 @@ ProjectionType::handle_substitions (SubstitutionArgumentMappings subst_mappings) return nullptr; } - auto new_field = concrete->clone (); - new_field->set_ref (fty->get_ref ()); - projection->base = new_field; + projection->base = concrete; } return projection; diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 17ba655..1f157c8 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -101,6 +101,8 @@ public: const TypeBoundPredicate *get_parent () const { return parent; } + Location get_locus () const; + private: const TypeBoundPredicate *parent; const Resolver::TraitItemReference *trait_item_ref; @@ -661,13 +663,16 @@ class SubstitutionArgumentMappings public: SubstitutionArgumentMappings (std::vector<SubstitutionArg> mappings, Location locus, - ParamSubstCb param_subst_cb = nullptr) - : mappings (mappings), locus (locus), param_subst_cb (param_subst_cb) + 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) {} SubstitutionArgumentMappings (const SubstitutionArgumentMappings &other) : mappings (other.mappings), locus (other.locus), - param_subst_cb (other.param_subst_cb) + param_subst_cb (other.param_subst_cb), + trait_item_flag (other.trait_item_flag) {} SubstitutionArgumentMappings & @@ -676,13 +681,14 @@ public: mappings = other.mappings; locus = other.locus; param_subst_cb = other.param_subst_cb; + trait_item_flag = other.trait_item_flag; return *this; } static SubstitutionArgumentMappings error () { - return SubstitutionArgumentMappings ({}, Location (), nullptr); + return SubstitutionArgumentMappings ({}, Location (), nullptr, false); } bool is_error () const { return mappings.size () == 0; } @@ -754,10 +760,15 @@ public: param_subst_cb (p, a); } + ParamSubstCb get_subst_cb () const { return param_subst_cb; } + + bool trait_item_mode () const { return trait_item_flag; } + private: std::vector<SubstitutionArg> mappings; Location locus; ParamSubstCb param_subst_cb; + bool trait_item_flag; }; class SubstitutionRef @@ -2296,8 +2307,9 @@ private: class ProjectionType : public BaseType, public SubstitutionRef { public: - ProjectionType (HirId ref, BaseType *base, Resolver::TraitReference *trait, - DefId item, std::vector<SubstitutionParamMapping> subst_refs, + ProjectionType (HirId ref, BaseType *base, + const Resolver::TraitReference *trait, DefId item, + std::vector<SubstitutionParamMapping> subst_refs, SubstitutionArgumentMappings generic_arguments = SubstitutionArgumentMappings::error (), std::set<HirId> refs = std::set<HirId> ()) @@ -2310,7 +2322,7 @@ public: {} ProjectionType (HirId ref, HirId ty_ref, BaseType *base, - Resolver::TraitReference *trait, DefId item, + const Resolver::TraitReference *trait, DefId item, std::vector<SubstitutionParamMapping> subst_refs, SubstitutionArgumentMappings generic_arguments = SubstitutionArgumentMappings::error (), @@ -2361,7 +2373,7 @@ public: private: BaseType *base; - Resolver::TraitReference *trait; + const Resolver::TraitReference *trait; DefId item; }; diff --git a/gcc/testsuite/rust/compile/traits9.rs b/gcc/testsuite/rust/compile/traits9.rs index 8d81bae..e1aef539 100644 --- a/gcc/testsuite/rust/compile/traits9.rs +++ b/gcc/testsuite/rust/compile/traits9.rs @@ -1,4 +1,3 @@ -// { dg-additional-options -frust-crate=example } struct Foo(i32); trait Bar { fn baz(&self); @@ -9,6 +8,6 @@ fn main() { a = Foo(123); let b: &dyn Bar = &a; - // { dg-error "bounds not satisfied for Foo .example::Bar. is not satisfied" "" { target *-*-* } .-1 } + // { dg-error "bounds not satisfied for Foo .Bar. is not satisfied" "" { target *-*-* } .-1 } // { dg-error "expected" "" { target *-*-* } .-2 } } diff --git a/gcc/testsuite/rust/execute/torture/issue-1120.rs b/gcc/testsuite/rust/execute/torture/issue-1120.rs new file mode 100644 index 0000000..ecbc6b2 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-1120.rs @@ -0,0 +1,123 @@ +// { dg-additional-options "-w" } +extern "rust-intrinsic" { + pub fn offset<T>(dst: *const T, offset: isize) -> *const T; +} + +struct FatPtr<T> { + data: *const T, + len: usize, +} + +pub union Repr<T> { + rust: *const [T], + rust_mut: *mut [T], + raw: FatPtr<T>, +} + +pub enum Option<T> { + None, + Some(T), +} + +#[lang = "Range"] +pub struct Range<Idx> { + pub start: Idx, + pub end: Idx, +} + +#[lang = "const_slice_ptr"] +impl<T> *const [T] { + pub const fn len(self) -> usize { + let a = unsafe { Repr { rust: self }.raw }; + a.len + } + + pub const fn as_ptr(self) -> *const T { + self as *const T + } +} + +#[lang = "const_ptr"] +impl<T> *const T { + pub const unsafe fn offset(self, count: isize) -> *const T { + unsafe { offset(self, count) } + } + + pub const unsafe fn add(self, count: usize) -> Self { + unsafe { self.offset(count as isize) } + } + + pub const fn as_ptr(self) -> *const T { + self as *const T + } +} + +const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] { + unsafe { + Repr { + raw: FatPtr { data, len }, + } + .rust + } +} + +#[lang = "index"] +trait Index<Idx> { + type Output; + + fn index(&self, index: Idx) -> &Self::Output; +} + +pub unsafe trait SliceIndex<T> { + type Output; + + fn get(self, slice: &T) -> Option<&Self::Output>; + + unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output; + + fn index(self, slice: &T) -> &Self::Output; +} + +unsafe impl<T> SliceIndex<[T]> for Range<usize> { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&[T]> { + if self.start > self.end + /* || self.end > slice.len() */ + { + Option::None + } else { + unsafe { Option::Some(&*self.get_unchecked(slice)) } + } + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + unsafe { + let a: *const T = slice.as_ptr(); + let b: *const T = a.add(self.start); + slice_from_raw_parts(b, self.end - self.start) + } + } + + fn index(self, slice: &[T]) -> &[T] { + unsafe { &*self.get_unchecked(slice) } + } +} + +impl<T, I> Index<I> for [T] +where + I: SliceIndex<[T]>, +{ + type Output = I::Output; + + fn index(&self, index: I) -> &I::Output { + index.index(self) + } +} + +fn main() -> i32 { + let a = [1, 2, 3, 4, 5]; + let b = &a[1..3]; + + 0 +} |