diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-08-08 22:22:21 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-08 22:22:21 +0000 |
commit | 5e723d0b7a85d109f01196b264a25823e77496e1 (patch) | |
tree | 33b8a34539ea3121c5f27ba1e44640f552f52a64 | |
parent | fa2aec10e60592348e1640b5bda0507b1324f235 (diff) | |
parent | 72483b1ca912dca78543f5cc2a7e9d1380ef5784 (diff) | |
download | gcc-5e723d0b7a85d109f01196b264a25823e77496e1.zip gcc-5e723d0b7a85d109f01196b264a25823e77496e1.tar.gz gcc-5e723d0b7a85d109f01196b264a25823e77496e1.tar.bz2 |
Merge #611
611: Add check for TypeBounds on argument substitutions r=philberty a=philberty
TypeParameters contain specified bounds, when we substitute them we need
to ensure that the argument satisfies those bounds otherwise... it fails
the contract.
Addreses #440
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 6 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 6 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-path-probe.h | 50 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-ref.h | 16 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-resolve.h | 26 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-bounds.h | 5 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-base.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 4 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-item.h | 14 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.h | 5 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.h | 4 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-bounds.cc | 26 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 77 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 53 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.cc | 7 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.h | 14 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/traits6.rs | 15 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/traits7.rs | 24 |
18 files changed, 258 insertions, 96 deletions
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index c87b477..5f07a2a 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -107,10 +107,10 @@ ResolvePathRef::visit (HIR::PathInExpression &expr) = ctx->get_mappings ()->lookup_trait_item_mapping ( trait_item->get_mappings ().get_hirid ()); - Resolver::TraitReference &trait_ref - = Resolver::TraitResolver::error_node (); + Resolver::TraitReference *trait_ref + = &Resolver::TraitReference::error_node (); bool ok = ctx->get_tyctx ()->lookup_trait_reference ( - trait->get_mappings ().get_defid (), trait_ref); + trait->get_mappings ().get_defid (), &trait_ref); rust_assert (ok); TyTy::BaseType *receiver = nullptr; diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index f422572..3c6a188 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -150,10 +150,10 @@ CompileExpr::visit (HIR::MethodCallExpr &expr) HIR::Trait *trait = ctx->get_mappings ()->lookup_trait_item_mapping ( trait_item->get_mappings ().get_hirid ()); - Resolver::TraitReference &trait_ref - = Resolver::TraitResolver::error_node (); + Resolver::TraitReference *trait_ref + = &Resolver::TraitReference::error_node (); bool ok = ctx->get_tyctx ()->lookup_trait_reference ( - trait->get_mappings ().get_defid (), trait_ref); + trait->get_mappings ().get_defid (), &trait_ref); rust_assert (ok); TyTy::BaseType *receiver = nullptr; diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h index 8e3ca31..87c9662 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.h +++ b/gcc/rust/typecheck/rust-hir-path-probe.h @@ -49,8 +49,8 @@ struct PathProbeCandidate struct TraitItemCandidate { - const TraitReference &trait_ref; - const TraitItemReference &item_ref; + const TraitReference *trait_ref; + const TraitItemReference *item_ref; }; CandidateType type; @@ -128,18 +128,18 @@ public: if (!probe_bounds) return probe.candidates; - std::vector<std::reference_wrapper<TraitReference>> probed_bounds + std::vector<TraitReference *> probed_bounds = TypeBoundsProbe::Probe (receiver); - std::vector<std::reference_wrapper<const TraitReference>> specified_bounds; + std::vector<const TraitReference *> specified_bounds; for (const TyTy::TypeBoundPredicate &predicate : receiver->get_specified_bounds ()) { const TraitReference *trait_item = predicate.get (); - specified_bounds.push_back (*trait_item); + specified_bounds.push_back (trait_item); } - std::vector<std::reference_wrapper<const TraitReference>> union_type_bounds + std::vector<const TraitReference *> union_type_bounds = probe.union_bounds (probed_bounds, specified_bounds); probe.process_traits_for_candidates (union_type_bounds, ignore_mandatory_trait_items); @@ -230,22 +230,22 @@ private: } void process_traits_for_candidates ( - const std::vector<std::reference_wrapper<const TraitReference>> traits, + const std::vector<const TraitReference *> traits, bool ignore_mandatory_trait_items) { - for (const TraitReference &trait_ref : traits) + for (const TraitReference *trait_ref : traits) { - const TraitItemReference &trait_item_ref - = trait_ref.lookup_trait_item (search.as_string ()); - if (trait_item_ref.is_error ()) + const TraitItemReference *trait_item_ref = nullptr; + if (!trait_ref->lookup_trait_item (search.as_string (), + &trait_item_ref)) continue; - bool trait_item_needs_implementation = !trait_item_ref.is_optional (); + bool trait_item_needs_implementation = !trait_item_ref->is_optional (); if (ignore_mandatory_trait_items && trait_item_needs_implementation) continue; PathProbeCandidate::CandidateType candidate_type; - switch (trait_item_ref.get_trait_item_type ()) + switch (trait_item_ref->get_trait_item_type ()) { case TraitItemReference::TraitItemType::FN: candidate_type = PathProbeCandidate::CandidateType::TRAIT_FUNC; @@ -264,7 +264,7 @@ private: break; } - TyTy::BaseType *trait_item_tyty = trait_item_ref.get_tyty (); + TyTy::BaseType *trait_item_tyty = trait_item_ref->get_tyty (); // we can substitute the Self with the receiver here if (trait_item_tyty->get_kind () == TyTy::TypeKind::FNDEF) @@ -298,7 +298,7 @@ private: trait_ref, trait_item_ref}; PathProbeCandidate candidate{candidate_type, trait_item_tyty, - trait_ref.get_locus (), + trait_ref->get_locus (), {trait_item_candidate}}; candidates.push_back (std::move (candidate)); } @@ -311,21 +311,21 @@ private: current_impl (nullptr) {} - std::vector<std::reference_wrapper<const TraitReference>> union_bounds ( - const std::vector<std::reference_wrapper</*const*/ TraitReference>> a, - const std::vector<std::reference_wrapper<const TraitReference>> b) const + std::vector<const TraitReference *> + union_bounds (const std::vector</*const*/ TraitReference *> a, + const std::vector<const TraitReference *> b) const { - std::map<DefId, std::reference_wrapper<const TraitReference>> mapper; - for (const TraitReference &ref : a) + std::map<DefId, const TraitReference *> mapper; + for (const TraitReference *ref : a) { - mapper.insert ({ref.get_mappings ().get_defid (), ref}); + mapper.insert ({ref->get_mappings ().get_defid (), ref}); } - for (const TraitReference &ref : b) + for (const TraitReference *ref : b) { - mapper.insert ({ref.get_mappings ().get_defid (), ref}); + mapper.insert ({ref->get_mappings ().get_defid (), ref}); } - std::vector<std::reference_wrapper<const TraitReference>> union_set; + std::vector<const TraitReference *> union_set; for (auto it = mapper.begin (); it != mapper.end (); it++) { union_set.push_back (it->second); @@ -362,7 +362,7 @@ public: case PathProbeCandidate::CandidateType::TRAIT_ITEM_CONST: case PathProbeCandidate::CandidateType::TRAIT_TYPE_ALIAS: case PathProbeCandidate::CandidateType::TRAIT_FUNC: - r.add_range (c.item.trait.item_ref.get_locus ()); + r.add_range (c.item.trait.item_ref->get_locus ()); break; } } diff --git a/gcc/rust/typecheck/rust-hir-trait-ref.h b/gcc/rust/typecheck/rust-hir-trait-ref.h index b19c38a..21a8beb 100644 --- a/gcc/rust/typecheck/rust-hir-trait-ref.h +++ b/gcc/rust/typecheck/rust-hir-trait-ref.h @@ -199,6 +199,12 @@ public: bool is_error () const { return hir_trait_ref == nullptr; } + static TraitReference &error_node () + { + static TraitReference trait_error_node = TraitReference::error (); + return trait_error_node; + } + Location get_locus () const { return hir_trait_ref->get_locus (); } std::string get_name () const @@ -227,14 +233,18 @@ public: return hir_trait_ref->get_mappings (); } - const TraitItemReference &lookup_trait_item (const std::string &ident) const + bool lookup_trait_item (const std::string &ident, + const TraitItemReference **ref) const { for (auto &item : item_refs) { if (ident.compare (item.get_identifier ()) == 0) - return item; + { + *ref = &item; + return true; + } } - return TraitItemReference::error_node (); + return false; } const TraitItemReference & diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.h b/gcc/rust/typecheck/rust-hir-trait-resolve.h index 6d7c864..1669a37 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.h +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.h @@ -100,29 +100,23 @@ class TraitResolver : public TypeCheckBase using Rust::Resolver::TypeCheckBase::visit; public: - static TraitReference &Resolve (HIR::TypePath &path) + static TraitReference *Resolve (HIR::TypePath &path) { TraitResolver resolver; return resolver.go (path); } - static TraitReference &error_node () - { - static TraitReference trait_error_node = TraitReference::error (); - return trait_error_node; - } - private: TraitResolver () : TypeCheckBase () {} - TraitReference &go (HIR::TypePath &path) + TraitReference *go (HIR::TypePath &path) { NodeId ref; if (!resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (), &ref)) { rust_error_at (path.get_locus (), "Failed to resolve path to node-id"); - return error_node (); + return &TraitReference::error_node (); } HirId hir_node = UNKNOWN_HIRID; @@ -130,7 +124,7 @@ private: &hir_node)) { rust_error_at (path.get_locus (), "Failed to resolve path to hir-id"); - return error_node (); + return &TraitReference::error_node (); } HIR::Item *resolved_item @@ -140,9 +134,9 @@ private: resolved_item->accept_vis (*this); rust_assert (trait_reference != nullptr); - TraitReference &tref = error_node (); + TraitReference *tref = &TraitReference::error_node (); if (context->lookup_trait_reference ( - trait_reference->get_mappings ().get_defid (), tref)) + trait_reference->get_mappings ().get_defid (), &tref)) { return tref; } @@ -185,13 +179,13 @@ private: item_refs.push_back (std::move (trait_item_ref)); } - tref = TraitReference (trait_reference, item_refs); + TraitReference trait_object (trait_reference, item_refs); context->insert_trait_reference ( - trait_reference->get_mappings ().get_defid (), std::move (tref)); + trait_reference->get_mappings ().get_defid (), std::move (trait_object)); - tref = error_node (); + tref = &TraitReference::error_node (); bool ok = context->lookup_trait_reference ( - trait_reference->get_mappings ().get_defid (), tref); + trait_reference->get_mappings ().get_defid (), &tref); rust_assert (ok); return tref; diff --git a/gcc/rust/typecheck/rust-hir-type-bounds.h b/gcc/rust/typecheck/rust-hir-type-bounds.h index d97c0f5..ce694da 100644 --- a/gcc/rust/typecheck/rust-hir-type-bounds.h +++ b/gcc/rust/typecheck/rust-hir-type-bounds.h @@ -31,8 +31,7 @@ class TypeBoundsProbe : public TypeCheckBase using Rust::Resolver::TypeCheckBase::visit; public: - static std::vector<std::reference_wrapper<TraitReference>> - Probe (const TyTy::BaseType *receiver) + static std::vector<TraitReference *> Probe (const TyTy::BaseType *receiver) { TypeBoundsProbe probe (receiver); probe.scan (); @@ -48,7 +47,7 @@ private: {} const TyTy::BaseType *receiver; - std::vector<std::reference_wrapper<TraitReference>> trait_references; + std::vector<TraitReference *> trait_references; }; } // namespace Resolver diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h index f05ab86..3dd0a19 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-base.h +++ b/gcc/rust/typecheck/rust-hir-type-check-base.h @@ -202,7 +202,7 @@ protected: context (TypeCheckContext::get ()) {} - TraitReference &resolve_trait_path (HIR::TypePath &); + TraitReference *resolve_trait_path (HIR::TypePath &); Analysis::Mappings *mappings; Resolver *resolver; diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 7f1a83d..6743c8b 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -244,7 +244,7 @@ public: = resolved_candidate.is_impl_candidate () ? resolved_candidate.item.impl.impl_item->get_impl_mappings () .get_nodeid () - : resolved_candidate.item.trait.item_ref.get_mappings () + : resolved_candidate.item.trait.item_ref->get_mappings () .get_nodeid (); if (lookup_tyty->get_kind () != TyTy::TypeKind::FNDEF) @@ -994,7 +994,7 @@ public: else { resolved_node_id - = candidate.item.trait.item_ref.get_mappings ().get_nodeid (); + = candidate.item.trait.item_ref->get_mappings ().get_nodeid (); } if (seg.has_generic_args ()) diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h index 8d770f0..8775502 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-item.h +++ b/gcc/rust/typecheck/rust-hir-type-check-item.h @@ -43,12 +43,12 @@ public: void visit (HIR::ImplBlock &impl_block) override { - TraitReference &trait_reference = TraitResolver::error_node (); + TraitReference *trait_reference = &TraitReference::error_node (); if (impl_block.has_trait_ref ()) { std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref (); trait_reference = TraitResolver::Resolve (*ref.get ()); - rust_assert (!trait_reference.is_error ()); + rust_assert (!trait_reference->is_error ()); } TyTy::BaseType *self = nullptr; @@ -60,7 +60,7 @@ public: return; } - bool is_trait_impl_block = !trait_reference.is_error (); + bool is_trait_impl_block = !trait_reference->is_error (); std::vector<std::reference_wrapper<const TraitItemReference>> trait_item_refs; @@ -72,20 +72,20 @@ public: { auto &trait_item_ref = TypeCheckImplItemWithTrait::Resolve (impl_item.get (), self, - trait_reference); + *trait_reference); trait_item_refs.push_back (trait_item_ref); } } bool impl_block_missing_trait_items = is_trait_impl_block - && trait_reference.size () != trait_item_refs.size (); + && trait_reference->size () != trait_item_refs.size (); if (impl_block_missing_trait_items) { // 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 (auto &trait_item_ref : trait_reference->get_trait_items ()) { bool found = false; for (const TraitItemReference &implemented_trait_item : @@ -120,7 +120,7 @@ public: rust_error_at (r, "missing %s in implementation of trait %<%s%>", missing_items_buf.c_str (), - trait_reference.get_name ().c_str ()); + trait_reference->get_name ().c_str ()); } } } diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h index 91d9c53..fff86be 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.h +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h @@ -280,8 +280,11 @@ public: case HIR::TypeParamBound::BoundType::TRAITBOUND: { HIR::TraitBound *b = static_cast<HIR::TraitBound *> (bound.get ()); + + TraitReference *trait = resolve_trait_path (b->get_path ()); TyTy::TypeBoundPredicate predicate ( - &resolve_trait_path (b->get_path ())); + trait->get_mappings ().get_defid (), b->get_locus ()); + specified_bounds.push_back (std::move (predicate)); } break; diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h index b171123..d834ad8 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.h +++ b/gcc/rust/typecheck/rust-hir-type-check.h @@ -92,13 +92,13 @@ public: trait_context.emplace (id, std::move (ref)); } - bool lookup_trait_reference (DefId id, TraitReference &ref) + bool lookup_trait_reference (DefId id, TraitReference **ref) { auto it = trait_context.find (id); if (it == trait_context.end ()) return false; - ref = it->second; + *ref = &it->second; return true; } diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc index a480155..008dc19 100644 --- a/gcc/rust/typecheck/rust-tyty-bounds.cc +++ b/gcc/rust/typecheck/rust-tyty-bounds.cc @@ -48,14 +48,14 @@ TypeBoundsProbe::scan () for (auto &trait_path : possible_trait_paths) { - TraitReference &trait_ref = TraitResolver::Resolve (*trait_path); + TraitReference *trait_ref = TraitResolver::Resolve (*trait_path); - if (!trait_ref.is_error ()) + if (!trait_ref->is_error ()) trait_references.push_back (trait_ref); } } -TraitReference & +TraitReference * TypeCheckBase::resolve_trait_path (HIR::TypePath &path) { return TraitResolver::Resolve (path); @@ -68,7 +68,25 @@ namespace TyTy { std::string TypeBoundPredicate::as_string () const { - return reference->as_string (); + return get ()->as_string (); +} + +const Resolver::TraitReference * +TypeBoundPredicate::get () const +{ + auto context = Resolver::TypeCheckContext::get (); + + Resolver::TraitReference *ref = nullptr; + bool ok = context->lookup_trait_reference (reference, &ref); + rust_assert (ok); + + return ref; +} + +std::string +TypeBoundPredicate::get_name () const +{ + return get ()->get_name (); } } // namespace TyTy diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index a2ae4fa..2d165c3 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -27,6 +27,8 @@ #include "rust-tyty-cast.h" #include "rust-hir-map.h" #include "rust-substitution-mapper.h" +#include "rust-hir-trait-ref.h" +#include "rust-hir-type-bounds.h" extern ::Backend * rust_get_backend (); @@ -34,6 +36,75 @@ rust_get_backend (); namespace Rust { namespace TyTy { +bool +BaseType::satisfies_bound (const TypeBoundPredicate &predicate) const +{ + const Resolver::TraitReference *query = predicate.get (); + for (auto &bound : specified_bounds) + { + const Resolver::TraitReference *item = bound.get (); + bool found = item->get_mappings ().get_defid () + == query->get_mappings ().get_defid (); + if (found) + return true; + } + + std::vector<Resolver::TraitReference *> probed + = Resolver::TypeBoundsProbe::Probe (this); + for (const Resolver::TraitReference *bound : probed) + { + bool found = bound->get_mappings ().get_defid () + == query->get_mappings ().get_defid (); + if (found) + return true; + } + + return false; +} + +bool +BaseType::bounds_compatible (const BaseType &other, Location locus) const +{ + std::vector<std::reference_wrapper<const TypeBoundPredicate>> + unsatisfied_bounds; + for (auto &bound : get_specified_bounds ()) + { + if (!other.satisfies_bound (bound)) + unsatisfied_bounds.push_back (bound); + } + + // lets emit a single error for this + if (unsatisfied_bounds.size () > 0) + { + RichLocation r (locus); + std::string missing_preds; + for (size_t i = 0; i < unsatisfied_bounds.size (); i++) + { + const TypeBoundPredicate &pred = unsatisfied_bounds.at (i); + r.add_range (pred.get_locus ()); + missing_preds += pred.get_name (); + + bool have_next = (i + 1) < unsatisfied_bounds.size (); + if (have_next) + missing_preds += ", "; + } + + rust_error_at (r, "bounds not satisfied for %s %<%s%> is not satisfied", + other.get_name ().c_str (), missing_preds.c_str ()); + } + + return unsatisfied_bounds.size () == 0; +} + +void +BaseType::inherit_bounds (const BaseType &other) +{ + for (auto &bound : other.get_specified_bounds ()) + { + add_bound (bound); + } +} + TyVar::TyVar (HirId ref) : ref (ref) { // ensure this reference is defined within the context @@ -556,7 +627,7 @@ ADTType::handle_substitions (SubstitutionArgumentMappings subst_mappings) bool ok = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg); if (ok) - sub.fill_param_ty (arg.get_tyty ()); + sub.fill_param_ty (arg.get_tyty (), subst_mappings.get_locus ()); } adt->iterate_fields ([&] (StructFieldType *field) mutable -> bool { @@ -811,7 +882,7 @@ FnType::is_equal (const BaseType &other) const BaseType * FnType::clone () const { - std::vector<std::pair<HIR::Pattern *, BaseType *> > cloned_params; + std::vector<std::pair<HIR::Pattern *, BaseType *>> cloned_params; for (auto &p : params) cloned_params.push_back ( std::pair<HIR::Pattern *, BaseType *> (p.first, p.second->clone ())); @@ -836,7 +907,7 @@ FnType::handle_substitions (SubstitutionArgumentMappings subst_mappings) bool ok = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg); if (ok) - sub.fill_param_ty (arg.get_tyty ()); + sub.fill_param_ty (arg.get_tyty (), subst_mappings.get_locus ()); } auto fty = fn->get_return_type (); diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 13bab90..c1afa14 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -132,26 +132,21 @@ public: class TypeBoundPredicate { public: - TypeBoundPredicate (Resolver::TraitReference *reference) - : reference (reference) + TypeBoundPredicate (DefId reference, Location locus) + : reference (reference), locus (locus) {} - TypeBoundPredicate (const TypeBoundPredicate &other) - : reference (other.reference) - {} + std::string as_string () const; - TypeBoundPredicate &operator= (const TypeBoundPredicate &other) - { - reference = other.reference; - return *this; - } + const Resolver::TraitReference *get () const; - std::string as_string () const; + Location get_locus () const { return locus; } - const Resolver::TraitReference *get () const { return reference; } + std::string get_name () const; private: - Resolver::TraitReference *reference; + DefId reference; + Location locus; }; class TypeBoundsMappings @@ -172,7 +167,21 @@ public: return specified_bounds; } + std::string bounds_as_string () const + { + std::string buf; + for (auto &b : specified_bounds) + buf += b.as_string () + ", "; + + return "bounds:[" + buf + "]"; + } + protected: + void add_bound (TypeBoundPredicate predicate) + { + specified_bounds.push_back (predicate); + } + std::vector<TypeBoundPredicate> specified_bounds; }; @@ -237,6 +246,12 @@ public: return get_kind () == other.get_kind (); } + bool satisfies_bound (const TypeBoundPredicate &predicate) const; + + bool bounds_compatible (const BaseType &other, Location locus) const; + + void inherit_bounds (const BaseType &other); + virtual bool is_unit () const { return false; } virtual bool is_concrete () const { return true; } @@ -575,8 +590,18 @@ public: std::string as_string () const { return param->as_string (); } - void fill_param_ty (BaseType *type) + void fill_param_ty (BaseType *type, Location locus) { + if (type->get_kind () == TyTy::TypeKind::INFER) + { + type->inherit_bounds (*param); + } + else + { + if (!param->bounds_compatible (*type, locus)) + return; + } + if (type->get_kind () == TypeKind::PARAM) { delete param; diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index 4ffbff0..0f8f902 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -23,13 +23,6 @@ namespace Rust { namespace Analysis { -NodeMapping::NodeMapping (CrateNum crateNum, NodeId nodeId, HirId hirId, - LocalDefId localDefId) - : crateNum (crateNum), nodeId (nodeId), hirId (hirId), localDefId (localDefId) -{} - -NodeMapping::~NodeMapping () {} - NodeMapping NodeMapping::get_error () { diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h index ccc873b..f689abf 100644 --- a/gcc/rust/util/rust-hir-map.h +++ b/gcc/rust/util/rust-hir-map.h @@ -53,8 +53,10 @@ class NodeMapping { public: NodeMapping (CrateNum crateNum, NodeId nodeId, HirId hirId, - LocalDefId localDefId); - ~NodeMapping (); + LocalDefId localDefId) + : crateNum (crateNum), nodeId (nodeId), hirId (hirId), + localDefId (localDefId) + {} static NodeMapping get_error (); @@ -68,6 +70,14 @@ public: std::string as_string () const; + bool is_equal (const NodeMapping &other) const + { + return get_crate_num () == other.get_crate_num () + && get_nodeid () == other.get_nodeid () + && get_hirid () == other.get_hirid () + && get_local_defid () == other.get_local_defid (); + } + private: CrateNum crateNum; NodeId nodeId; diff --git a/gcc/testsuite/rust/compile/traits6.rs b/gcc/testsuite/rust/compile/traits6.rs new file mode 100644 index 0000000..3579b5a --- /dev/null +++ b/gcc/testsuite/rust/compile/traits6.rs @@ -0,0 +1,15 @@ +trait Foo { + fn default() -> i32; +} + +struct Bar(i32); + +fn type_bound_test<T: Foo>() -> i32 { + T::default() +} + +fn main() { + let a; + a = type_bound_test::<Bar>(); + // { dg-error "bounds not satisfied for Bar" "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/traits7.rs b/gcc/testsuite/rust/compile/traits7.rs new file mode 100644 index 0000000..825553c --- /dev/null +++ b/gcc/testsuite/rust/compile/traits7.rs @@ -0,0 +1,24 @@ +trait Foo { + fn default() -> i32; +} + +trait Bar { + fn not_default() -> i32; +} + +struct Test(i32); + +impl Foo for Test { + fn default() -> i32 { + 1234 + } +} + +fn type_bound_test<T: Foo + Bar>() -> i32 { + T::default() +} + +fn main() { + let a = type_bound_test::<Test>(); + // { dg-error "bounds not satisfied for Test" "" { target *-*-* } .-1 } +} |