diff options
Diffstat (limited to 'gcc/rust/backend/rust-compile-resolve-path.cc')
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 148 |
1 files changed, 95 insertions, 53 deletions
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index 69599cc..2b6880c 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -32,18 +32,41 @@ namespace Rust { namespace Compile { -void -ResolvePathRef::visit (HIR::QualifiedPathInExpression &expr) +tree +ResolvePathRef::Compile (HIR::QualifiedPathInExpression &expr, Context *ctx) { - resolved = resolve (expr.get_final_segment ().get_segment (), - expr.get_mappings (), expr.get_locus (), true); + ResolvePathRef resolver (ctx); + return resolver.resolve_path_like (expr); } -void -ResolvePathRef::visit (HIR::PathInExpression &expr) +tree +ResolvePathRef::Compile (HIR::PathInExpression &expr, Context *ctx) { - resolved = resolve (expr.get_final_segment ().get_segment (), - expr.get_mappings (), expr.get_locus (), false); + ResolvePathRef resolver (ctx); + return resolver.resolve_path_like (expr); +} + +ResolvePathRef::ResolvePathRef (Context *ctx) : HIRCompileBase (ctx) {} + +template <typename T> +tree +ResolvePathRef::resolve_path_like (T &expr) +{ + if (expr.is_lang_item ()) + { + auto lang_item + = Analysis::Mappings::get ().get_lang_item_node (expr.get_lang_item ()); + + // FIXME: Is that correct? :/ + auto final_segment + = HIR::PathIdentSegment (LangItem::ToString (expr.get_lang_item ())); + + return resolve_with_node_id (final_segment, expr.get_mappings (), + expr.get_locus (), true, lang_item); + } + + return resolve (expr.get_final_segment ().get_segment (), + expr.get_mappings (), expr.get_locus (), true); } tree @@ -92,42 +115,17 @@ ResolvePathRef::attempt_constructor_expression_lookup ( } tree -ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, - const Analysis::NodeMapping &mappings, - location_t expr_locus, bool is_qualified_path) +ResolvePathRef::resolve_with_node_id ( + const HIR::PathIdentSegment &final_segment, + const Analysis::NodeMapping &mappings, location_t expr_locus, + bool is_qualified_path, NodeId resolved_node_id) { TyTy::BaseType *lookup = nullptr; bool ok = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &lookup); rust_assert (ok); - // need to look up the reference for this identifier - - // this can fail because it might be a Constructor for something - // in that case the caller should attempt ResolvePathType::Compile - NodeId ref_node_id = UNKNOWN_NODEID; - if (flag_name_resolution_2_0) - { - auto nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - - auto resolved = nr_ctx.lookup (mappings.get_nodeid ()); - - if (!resolved) - return attempt_constructor_expression_lookup (lookup, ctx, mappings, - expr_locus); - - ref_node_id = *resolved; - } - else - { - if (!ctx->get_resolver ()->lookup_resolved_name (mappings.get_nodeid (), - &ref_node_id)) - return attempt_constructor_expression_lookup (lookup, ctx, mappings, - expr_locus); - } - tl::optional<HirId> hid - = ctx->get_mappings ().lookup_node_to_hir (ref_node_id); + = ctx->get_mappings ().lookup_node_to_hir (resolved_node_id); if (!hid.has_value ()) { rust_error_at (expr_locus, "reverse call path lookup failure"); @@ -186,6 +184,11 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, } } + // Handle unit struct + if (lookup->get_kind () == TyTy::TypeKind::ADT) + return attempt_constructor_expression_lookup (lookup, ctx, mappings, + expr_locus); + // let the query system figure it out tree resolved_item = query_compile (ref, lookup, final_segment, mappings, expr_locus, is_qualified_path); @@ -193,10 +196,50 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, { TREE_USED (resolved_item) = 1; } + return resolved_item; } tree +ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, + const Analysis::NodeMapping &mappings, + location_t expr_locus, bool is_qualified_path) +{ + TyTy::BaseType *lookup = nullptr; + bool ok = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &lookup); + rust_assert (ok); + + // need to look up the reference for this identifier + + // this can fail because it might be a Constructor for something + // in that case the caller should attempt ResolvePathType::Compile + NodeId ref_node_id = UNKNOWN_NODEID; + if (flag_name_resolution_2_0) + { + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + + auto resolved = nr_ctx.lookup (mappings.get_nodeid ()); + + if (!resolved) + return attempt_constructor_expression_lookup (lookup, ctx, mappings, + expr_locus); + + ref_node_id = *resolved; + } + else + { + if (!ctx->get_resolver ()->lookup_resolved_name (mappings.get_nodeid (), + &ref_node_id)) + return attempt_constructor_expression_lookup (lookup, ctx, mappings, + expr_locus); + } + + return resolve_with_node_id (final_segment, mappings, expr_locus, + is_qualified_path, ref_node_id); +} + +tree HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, const HIR::PathIdentSegment &final_segment, const Analysis::NodeMapping &mappings, @@ -206,11 +249,9 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, if (auto resolved_item = ctx->get_mappings ().lookup_hir_item (ref)) { if (!lookup->has_substitutions_defined ()) - return CompileItem::compile (*resolved_item, ctx, nullptr, true, - expr_locus); + return CompileItem::compile (*resolved_item, ctx, nullptr, expr_locus); else - return CompileItem::compile (*resolved_item, ctx, lookup, true, - expr_locus); + return CompileItem::compile (*resolved_item, ctx, lookup, expr_locus); } else if (auto hir_extern_item = ctx->get_mappings ().lookup_hir_extern_item (ref)) @@ -248,12 +289,9 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, return CompileInherentImplItem::Compile (resolved_item->first, ctx, lookup, true, expr_locus); } - else + else if (auto trait_item + = ctx->get_mappings ().lookup_hir_trait_item (ref)) { - // it might be resolved to a trait item - tl::optional<HIR::TraitItem *> trait_item - = ctx->get_mappings ().lookup_hir_trait_item (ref); - HIR::Trait *trait = ctx->get_mappings ().lookup_trait_item_mapping ( trait_item.value ()->get_mappings ().get_hirid ()); @@ -263,16 +301,20 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, trait->get_mappings ().get_defid (), &trait_ref); rust_assert (ok); - TyTy::BaseType *receiver = nullptr; - ok = ctx->get_tyctx ()->lookup_receiver (mappings.get_hirid (), - &receiver); - rust_assert (ok); - receiver = receiver->destructure (); - // 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 + // + // because we know this is resolved to a trait item we can actually + // just grab the Self type parameter here for the receiver to match + // the appropriate impl block + + rust_assert (lookup->is<TyTy::FnType> ()); + auto fn = lookup->as<TyTy::FnType> (); + rust_assert (fn->get_num_type_params () > 0); + auto &self = fn->get_substs ().at (0); + auto receiver = self.get_param_ty (); auto candidates = Resolver::PathProbeImplTrait::Probe (receiver, final_segment, trait_ref); |