diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-08-05 21:33:47 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-05 21:33:47 +0000 |
commit | 935f1d7da3ea82980bed642c6eea06d69de5fdf6 (patch) | |
tree | bb7172a61dc354681743d86f708e021b4613cc9f /gcc/rust/backend/rust-compile-resolve-path.cc | |
parent | 074c070c02e61033694f2f969a33a795036ad540 (diff) | |
parent | 65ef30eb84314ae7525be4a4d7dd79d2868e3e3c (diff) | |
download | gcc-935f1d7da3ea82980bed642c6eea06d69de5fdf6.zip gcc-935f1d7da3ea82980bed642c6eea06d69de5fdf6.tar.gz gcc-935f1d7da3ea82980bed642c6eea06d69de5fdf6.tar.bz2 |
Merge #609
609: Initial TypeBounds support r=philberty a=philberty
This allows us to specify bounds on type parameters that influence
path resolution to allow us to resolve to trait items. More error
checking is required to actually enforce the trait constraint but
this patch is getting rather large and does not cause regressions.
Fixes #583
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust/backend/rust-compile-resolve-path.cc')
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 84 |
1 files changed, 75 insertions, 9 deletions
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index af8d609..c87b477 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -20,6 +20,8 @@ #include "rust-backend.h" #include "rust-compile-resolve-path.h" #include "rust-compile-item.h" +#include "rust-hir-trait-resolve.h" +#include "rust-hir-path-probe.h" namespace Rust { namespace Compile { @@ -94,7 +96,76 @@ ResolvePathRef::visit (HIR::PathInExpression &expr) HIR::ImplItem *resolved_item = ctx->get_mappings ()->lookup_hir_implitem ( expr.get_mappings ().get_crate_num (), ref, &parent_impl_id); - if (resolved_item != nullptr) + + if (resolved_item == nullptr) + { + // it might be resolved to a trait item + HIR::TraitItem *trait_item + = ctx->get_mappings ()->lookup_hir_trait_item ( + expr.get_mappings ().get_crate_num (), ref); + HIR::Trait *trait + = ctx->get_mappings ()->lookup_trait_item_mapping ( + trait_item->get_mappings ().get_hirid ()); + + Resolver::TraitReference &trait_ref + = Resolver::TraitResolver::error_node (); + bool ok = ctx->get_tyctx ()->lookup_trait_reference ( + trait->get_mappings ().get_defid (), trait_ref); + rust_assert (ok); + + TyTy::BaseType *receiver = nullptr; + ok = ctx->get_tyctx ()->lookup_receiver ( + expr.get_mappings ().get_hirid (), &receiver); + rust_assert (ok); + + if (receiver->get_kind () == TyTy::TypeKind::PARAM) + { + TyTy::ParamType *p + = static_cast<TyTy::ParamType *> (receiver); + receiver = p->resolve (); + } + + // the type resolver can only resolve type bounds to their trait + // item so its up to us to figure out if this path should resolve + // to an trait-impl-block-item or if it can be defaulted to the + // trait-impl-item's definition + std::vector<Resolver::PathProbeCandidate> candidates + = Resolver::PathProbeType::Probe ( + receiver, expr.get_final_segment ().get_segment (), true, + false, true); + + if (candidates.size () == 0) + { + // this means we are defaulting back to the trait_item if + // possible + // TODO + gcc_unreachable (); + } + else + { + Resolver::PathProbeCandidate &candidate = candidates.at (0); + rust_assert (candidate.is_impl_candidate ()); + + HIR::ImplBlock *impl = candidate.item.impl.parent; + HIR::ImplItem *impl_item = candidate.item.impl.impl_item; + + TyTy::BaseType *self = nullptr; + bool ok = ctx->get_tyctx ()->lookup_type ( + impl->get_type ()->get_mappings ().get_hirid (), &self); + rust_assert (ok); + + if (!lookup->has_subsititions_defined ()) + CompileInherentImplItem::Compile (self, impl_item, ctx, + true); + else + CompileInherentImplItem::Compile (self, impl_item, ctx, + true, lookup); + + lookup->set_ty_ref ( + impl_item->get_impl_mappings ().get_hirid ()); + } + } + else { rust_assert (parent_impl_id != UNKNOWN_HIRID); HIR::Item *impl_ref = ctx->get_mappings ()->lookup_hir_item ( @@ -114,18 +185,13 @@ ResolvePathRef::visit (HIR::PathInExpression &expr) CompileInherentImplItem::Compile (self, resolved_item, ctx, true, lookup); } - else - { - rust_error_at (expr.get_locus (), - "failed to lookup definition declaration"); - return; - } } if (!ctx->lookup_function_decl (lookup->get_ty_ref (), &fn)) { - rust_fatal_error (expr.get_locus (), - "forward declaration was not compiled"); + resolved = ctx->get_backend ()->error_expression (); + rust_error_at (expr.get_locus (), + "forward declaration was not compiled"); return; } } |