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.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.cc')
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 118 |
1 files changed, 97 insertions, 21 deletions
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index aa9aa2d..f422572 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -20,6 +20,8 @@ #include "rust-compile-item.h" #include "rust-compile-expr.h" #include "rust-compile-struct-field-expr.h" +#include "rust-hir-trait-resolve.h" +#include "rust-hir-path-probe.h" #include "fnv-hash.h" namespace Rust { @@ -141,31 +143,105 @@ CompileExpr::visit (HIR::MethodCallExpr &expr) expr.get_mappings ().get_crate_num (), ref, nullptr); if (resolved_item == nullptr) { - rust_error_at (expr.get_locus (), - "failed to lookup forward declaration"); - return; - } + // 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 (); + } - TyTy::BaseType *self_type = nullptr; - if (!ctx->get_tyctx ()->lookup_type ( - expr.get_receiver ()->get_mappings ().get_hirid (), &self_type)) - { - rust_error_at (expr.get_locus (), - "failed to resolve type for self param"); - return; - } + // 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_method_name ().get_segment (), true, false, + true); - if (!fntype->has_subsititions_defined ()) - CompileInherentImplItem::Compile (self_type, resolved_item, ctx, 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::ImplItem *impl_item = candidate.item.impl.impl_item; + + TyTy::BaseType *self_type = nullptr; + if (!ctx->get_tyctx ()->lookup_type ( + expr.get_receiver ()->get_mappings ().get_hirid (), + &self_type)) + { + rust_error_at (expr.get_locus (), + "failed to resolve type for self param"); + return; + } + + if (!fntype->has_subsititions_defined ()) + CompileInherentImplItem::Compile (self_type, impl_item, ctx, + true); + else + CompileInherentImplItem::Compile (self_type, impl_item, ctx, + true, fntype); + + if (!ctx->lookup_function_decl ( + impl_item->get_impl_mappings ().get_hirid (), &fn)) + { + translated = ctx->get_backend ()->error_expression (); + rust_error_at (expr.get_locus (), + "forward declaration was not compiled"); + return; + } + } + } else - CompileInherentImplItem::Compile (self_type, resolved_item, ctx, true, - fntype); - - if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &fn)) { - rust_error_at (expr.get_locus (), - "forward declaration was not compiled"); - return; + TyTy::BaseType *self_type = nullptr; + if (!ctx->get_tyctx ()->lookup_type ( + expr.get_receiver ()->get_mappings ().get_hirid (), &self_type)) + { + rust_error_at (expr.get_locus (), + "failed to resolve type for self param"); + return; + } + + if (!fntype->has_subsititions_defined ()) + CompileInherentImplItem::Compile (self_type, resolved_item, ctx, + true); + else + CompileInherentImplItem::Compile (self_type, resolved_item, ctx, + true, fntype); + + if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &fn)) + { + translated = ctx->get_backend ()->error_expression (); + rust_error_at (expr.get_locus (), + "forward declaration was not compiled"); + return; + } } } |