aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-ref.h22
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc4
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h160
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h10
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.h4
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.h9
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.cc86
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc18
-rw-r--r--gcc/rust/typecheck/rust-tyty.h28
-rw-r--r--gcc/testsuite/rust/compile/traits9.rs3
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1120.rs123
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 &param_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 = &param_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
+}