Line data Source code
1 : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
5 : // GCC is free software; you can redistribute it and/or modify it under
6 : // the terms of the GNU General Public License as published by the Free
7 : // Software Foundation; either version 3, or (at your option) any later
8 : // version.
9 :
10 : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : // for more details.
14 :
15 : // You should have received a copy of the GNU General Public License
16 : // along with GCC; see the file COPYING3. If not see
17 : // <http://www.gnu.org/licenses/>.
18 :
19 : #ifndef RUST_HIR_PATH_PROBE_H
20 : #define RUST_HIR_PATH_PROBE_H
21 :
22 : #include "rust-hir-type-check-base.h"
23 : #include "rust-hir-visitor.h"
24 : #include "rust-tyty.h"
25 :
26 : namespace Rust {
27 : namespace Resolver {
28 :
29 : struct PathProbeCandidate
30 : {
31 : enum CandidateType
32 : {
33 : ERROR,
34 :
35 : ENUM_VARIANT,
36 :
37 : IMPL_CONST,
38 : IMPL_TYPE_ALIAS,
39 : IMPL_FUNC,
40 :
41 : TRAIT_ITEM_CONST,
42 : TRAIT_TYPE_ALIAS,
43 : TRAIT_FUNC,
44 : };
45 :
46 : struct EnumItemCandidate
47 : {
48 : const TyTy::ADTType *parent;
49 : const TyTy::VariantDef *variant;
50 : };
51 :
52 : struct ImplItemCandidate
53 : {
54 : HIR::ImplItem *impl_item;
55 : HIR::ImplBlock *parent;
56 : };
57 :
58 : struct TraitItemCandidate
59 : {
60 : const TraitReference *trait_ref;
61 : const TraitItemReference *item_ref;
62 : HIR::ImplBlock *impl;
63 : };
64 :
65 : CandidateType type;
66 : TyTy::BaseType *ty;
67 : location_t locus;
68 : union Candidate
69 : {
70 : EnumItemCandidate enum_field;
71 : ImplItemCandidate impl;
72 : TraitItemCandidate trait;
73 :
74 : Candidate (EnumItemCandidate enum_field);
75 : Candidate (ImplItemCandidate impl);
76 : Candidate (TraitItemCandidate trait);
77 : } item;
78 :
79 : PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, location_t locus,
80 : EnumItemCandidate enum_field);
81 :
82 : PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, location_t locus,
83 : ImplItemCandidate impl);
84 :
85 : PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, location_t locus,
86 : TraitItemCandidate trait);
87 :
88 : std::string as_string () const;
89 :
90 : bool is_enum_candidate () const;
91 :
92 : bool is_impl_candidate () const;
93 :
94 : bool is_trait_candidate () const;
95 :
96 : bool is_full_trait_item_candidate () const;
97 :
98 : static PathProbeCandidate get_error ();
99 :
100 : bool is_error () const;
101 :
102 : DefId get_defid () const;
103 :
104 : bool operator< (const PathProbeCandidate &c) const;
105 : };
106 :
107 2245 : class PathProbeType : public TypeCheckBase, public HIR::HIRImplVisitor
108 : {
109 : public:
110 : static std::set<PathProbeCandidate>
111 : Probe (TyTy::BaseType *receiver, const HIR::PathIdentSegment &segment_name,
112 : bool probe_impls, bool probe_bounds, bool ignore_mandatory_trait_items,
113 : DefId specific_trait_id = UNKNOWN_DEFID);
114 :
115 : void visit (HIR::TypeAlias &alias) override;
116 : void visit (HIR::ConstantItem &constant) override;
117 : void visit (HIR::Function &function) override;
118 :
119 : protected:
120 : void process_enum_item_for_candiates (const TyTy::ADTType *adt);
121 :
122 : void process_impl_items_for_candidates ();
123 :
124 : void process_impl_item_candidate (HirId id, HIR::ImplItem *item,
125 : HIR::ImplBlock *impl);
126 :
127 : void
128 : process_associated_trait_for_candidates (const TraitReference *trait_ref,
129 : HIR::ImplBlock *impl,
130 : bool ignore_mandatory_trait_items);
131 :
132 : void
133 : process_predicate_for_candidates (const TyTy::TypeBoundPredicate &predicate,
134 : bool ignore_mandatory_trait_items);
135 :
136 : protected:
137 : PathProbeType (TyTy::BaseType *receiver, const HIR::PathIdentSegment &query,
138 : DefId specific_trait_id);
139 :
140 : std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>>
141 : union_bounds (
142 : const std::vector<std::pair</*const*/ TraitReference *, HIR::ImplBlock *>>
143 : a,
144 : const std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> b)
145 : const;
146 :
147 : bool is_receiver_generic () const;
148 :
149 : TyTy::BaseType *receiver;
150 : const HIR::PathIdentSegment &search;
151 : std::set<PathProbeCandidate> candidates;
152 : HIR::ImplBlock *current_impl;
153 : DefId specific_trait_id;
154 : };
155 :
156 : class ReportMultipleCandidateError : private TypeCheckBase
157 : {
158 : public:
159 1 : static void Report (std::set<PathProbeCandidate> &candidates,
160 : const HIR::PathIdentSegment &query,
161 : location_t query_locus)
162 : {
163 1 : rich_location r (line_table, query_locus);
164 3 : for (auto &c : candidates)
165 2 : r.add_range (c.locus);
166 :
167 3 : std::string rich_msg = "multiple " + query.to_string () + " found";
168 1 : r.add_fixit_replace (rich_msg.c_str ());
169 :
170 2 : rust_error_at (r, ErrorCode::E0034,
171 : "multiple applicable items in scope for: %qs",
172 2 : query.to_string ().c_str ());
173 1 : }
174 : };
175 :
176 1156 : class PathProbeImplTrait : public PathProbeType
177 : {
178 : public:
179 : static std::set<PathProbeCandidate>
180 : Probe (TyTy::BaseType *receiver, const HIR::PathIdentSegment &segment_name,
181 : const TraitReference *trait_reference);
182 :
183 : private:
184 : PathProbeImplTrait (TyTy::BaseType *receiver,
185 : const HIR::PathIdentSegment &query,
186 : const TraitReference *trait_reference);
187 :
188 : void process_trait_impl_items_for_candidates ();
189 :
190 : const TraitReference *trait_reference;
191 : };
192 :
193 : } // namespace Resolver
194 : } // namespace Rust
195 :
196 : #endif // RUST_HIR_PATH_PROBE_H
|