diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-04-19 16:33:48 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-19 16:33:48 +0000 |
commit | 4152743451a73591fa60bc52f0b28447ef4a8878 (patch) | |
tree | 9f14d6ba86b46d6eb778df421be3927e99d9da0e /gcc/rust | |
parent | 5b14291b54fe72407b840631511d1c3bb07df22e (diff) | |
parent | ad9e185e15fcfea8d23b03acccc26dab4e45bf45 (diff) | |
download | gcc-4152743451a73591fa60bc52f0b28447ef4a8878.zip gcc-4152743451a73591fa60bc52f0b28447ef4a8878.tar.gz gcc-4152743451a73591fa60bc52f0b28447ef4a8878.tar.bz2 |
Merge #1121
1121: Fix bad projection substitution r=philberty a=philberty
When we have a Trait such as:
```
pub unsafe trait SliceIndex<T> {
type Output;
fn index(self, slice: &T) -> &Self::Output;
}
unsafe impl<T> SliceIndex<[T]> for Range<usize> {
type Output = [T];
fn index(self, slice: &[T]) -> &[T] {
unsafe { &*self.get_unchecked(slice) }
}
}
```
When we need to verify that the impl index is compatible fir SliceIndex we
get the Type info for the trait-item which is:
fn<Self, T> index(self: Self, slice: &T)
-> &<placeholder=projection<T>=[T]>
This projection gets setup and the types are substituted with
Self=Range<usize> and T=[T] which ended up substituting the projection
twice resulting in a recursive slice [T=[T]]. In this case the associated
type is already setup for the placeholder and does not require generic
substitution. This means we added a flag to the substitution generic
arguments mappings to handle this case.
This patch also addressed memory corruption with the TypeBoundPredicate
as part of the debugging of this issue which resulted in a segv when
trying to debug the mappings. The issue was the copy constructors needed
to update the used argument mappings each time since the substitution param
mappings are copied and the addresses no longer exist, valgrind was great
here to find this issue.
Fixes #1120
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust')
-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 |
9 files changed, 208 insertions, 133 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; }; |