Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 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 : 2429 : class PathProbeType : public TypeCheckBase, public HIR::HIRImplVisitor
108 : : {
109 : : public:
110 : : static std::set<PathProbeCandidate>
111 : : Probe (const TyTy::BaseType *receiver,
112 : : const HIR::PathIdentSegment &segment_name, bool probe_impls,
113 : : bool probe_bounds, bool ignore_mandatory_trait_items,
114 : : DefId specific_trait_id = UNKNOWN_DEFID);
115 : :
116 : : void visit (HIR::TypeAlias &alias) override;
117 : : void visit (HIR::ConstantItem &constant) override;
118 : : void visit (HIR::Function &function) override;
119 : :
120 : : protected:
121 : : void process_enum_item_for_candiates (const TyTy::ADTType *adt);
122 : :
123 : : void process_impl_items_for_candidates ();
124 : :
125 : : void process_impl_item_candidate (HirId id, HIR::ImplItem *item,
126 : : HIR::ImplBlock *impl);
127 : :
128 : : void
129 : : process_associated_trait_for_candidates (const TraitReference *trait_ref,
130 : : HIR::ImplBlock *impl,
131 : : bool ignore_mandatory_trait_items);
132 : :
133 : : void
134 : : process_predicate_for_candidates (const TyTy::TypeBoundPredicate &predicate,
135 : : bool ignore_mandatory_trait_items);
136 : :
137 : : protected:
138 : : PathProbeType (const TyTy::BaseType *receiver,
139 : : const HIR::PathIdentSegment &query, DefId specific_trait_id);
140 : :
141 : : std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>>
142 : : union_bounds (
143 : : const std::vector<std::pair</*const*/ TraitReference *, HIR::ImplBlock *>>
144 : : a,
145 : : const std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> b)
146 : : const;
147 : :
148 : : bool is_reciever_generic () const;
149 : :
150 : : const TyTy::BaseType *receiver;
151 : : const HIR::PathIdentSegment &search;
152 : : std::set<PathProbeCandidate> candidates;
153 : : HIR::ImplBlock *current_impl;
154 : : DefId specific_trait_id;
155 : : };
156 : :
157 : : class ReportMultipleCandidateError : private TypeCheckBase
158 : : {
159 : : public:
160 : 1 : static void Report (std::set<PathProbeCandidate> &candidates,
161 : : const HIR::PathIdentSegment &query,
162 : : location_t query_locus)
163 : : {
164 : 1 : rich_location r (line_table, query_locus);
165 : 3 : for (auto &c : candidates)
166 : 2 : r.add_range (c.locus);
167 : :
168 : 2 : std::string rich_msg = "multiple " + query.as_string () + " found";
169 : 1 : r.add_fixit_replace (rich_msg.c_str ());
170 : :
171 : 1 : rust_error_at (r, ErrorCode::E0034,
172 : : "multiple applicable items in scope for: %qs",
173 : 2 : query.as_string ().c_str ());
174 : 1 : }
175 : : };
176 : :
177 : 415 : class PathProbeImplTrait : public PathProbeType
178 : : {
179 : : public:
180 : : static std::set<PathProbeCandidate>
181 : : Probe (const TyTy::BaseType *receiver,
182 : : const HIR::PathIdentSegment &segment_name,
183 : : const TraitReference *trait_reference);
184 : :
185 : : private:
186 : : PathProbeImplTrait (const TyTy::BaseType *receiver,
187 : : const HIR::PathIdentSegment &query,
188 : : const TraitReference *trait_reference);
189 : :
190 : : void process_trait_impl_items_for_candidates ();
191 : :
192 : : const TraitReference *trait_reference;
193 : : };
194 : :
195 : : } // namespace Resolver
196 : : } // namespace Rust
197 : :
198 : : #endif // RUST_HIR_PATH_PROBE_H
|