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 : : #include "rust-substitution-mapper.h"
20 : : #include "rust-hir-type-check.h"
21 : :
22 : : namespace Rust {
23 : : namespace Resolver {
24 : :
25 : 4215 : SubstMapper::SubstMapper (HirId ref, HIR::GenericArgs *generics,
26 : : const std::vector<TyTy::Region> ®ions,
27 : 4215 : location_t locus)
28 : 4215 : : resolved (new TyTy::ErrorType (ref)), generics (generics),
29 : 4215 : regions (regions), locus (locus)
30 : 4215 : {}
31 : :
32 : : TyTy::BaseType *
33 : 4215 : SubstMapper::Resolve (TyTy::BaseType *base, location_t locus,
34 : : HIR::GenericArgs *generics,
35 : : const std::vector<TyTy::Region> ®ions)
36 : : {
37 : 4215 : SubstMapper mapper (base->get_ref (), generics, regions, locus);
38 : 4215 : base->accept_vis (mapper);
39 : 4215 : rust_assert (mapper.resolved != nullptr);
40 : 4215 : return mapper.resolved;
41 : : }
42 : :
43 : : TyTy::BaseType *
44 : 2562 : SubstMapper::InferSubst (TyTy::BaseType *base, location_t locus)
45 : : {
46 : 2562 : return SubstMapper::Resolve (base, locus, nullptr, {});
47 : : }
48 : :
49 : : bool
50 : 4215 : SubstMapper::have_generic_args () const
51 : : {
52 : 4215 : return generics != nullptr;
53 : : }
54 : :
55 : : void
56 : 2042 : SubstMapper::visit (TyTy::FnType &type)
57 : : {
58 : 2042 : TyTy::FnType *concrete = nullptr;
59 : 2042 : if (!have_generic_args ())
60 : : {
61 : 1660 : TyTy::BaseType *substs = type.infer_substitions (locus);
62 : 1660 : rust_assert (substs->get_kind () == TyTy::TypeKind::FNDEF);
63 : : concrete = static_cast<TyTy::FnType *> (substs);
64 : : }
65 : : else
66 : : {
67 : 382 : TyTy::SubstitutionArgumentMappings mappings
68 : 382 : = type.get_mappings_from_generic_args (*generics, regions);
69 : 382 : if (mappings.is_error ())
70 : 0 : return;
71 : :
72 : 382 : concrete = type.handle_substitions (mappings);
73 : 382 : }
74 : :
75 : 382 : if (concrete != nullptr)
76 : 2042 : resolved = concrete;
77 : : }
78 : :
79 : : void
80 : 2173 : SubstMapper::visit (TyTy::ADTType &type)
81 : : {
82 : 2173 : TyTy::ADTType *concrete = nullptr;
83 : 2173 : if (!have_generic_args ())
84 : : {
85 : 902 : TyTy::BaseType *substs = type.infer_substitions (locus);
86 : 902 : rust_assert (substs->get_kind () == TyTy::TypeKind::ADT);
87 : : concrete = static_cast<TyTy::ADTType *> (substs);
88 : : }
89 : : else
90 : : {
91 : 1271 : TyTy::SubstitutionArgumentMappings mappings
92 : 1271 : = type.get_mappings_from_generic_args (*generics, regions);
93 : 1271 : if (mappings.is_error ())
94 : 5 : return;
95 : :
96 : 1266 : concrete = type.handle_substitions (mappings);
97 : 1271 : }
98 : :
99 : 1266 : if (concrete != nullptr)
100 : 2168 : resolved = concrete;
101 : : }
102 : :
103 : : void
104 : 0 : SubstMapper::visit (TyTy::PlaceholderType &type)
105 : : {
106 : 0 : rust_assert (type.can_resolve ());
107 : 0 : resolved = SubstMapper::Resolve (type.resolve (), locus, generics, regions);
108 : 0 : }
109 : :
110 : : void
111 : 0 : SubstMapper::visit (TyTy::ProjectionType &type)
112 : : {
113 : 0 : TyTy::ProjectionType *concrete = nullptr;
114 : 0 : if (!have_generic_args ())
115 : : {
116 : 0 : TyTy::BaseType *substs = type.infer_substitions (locus);
117 : 0 : rust_assert (substs->get_kind () == TyTy::TypeKind::PROJECTION);
118 : : concrete = static_cast<TyTy::ProjectionType *> (substs);
119 : : }
120 : : else
121 : : {
122 : 0 : TyTy::SubstitutionArgumentMappings mappings
123 : 0 : = type.get_mappings_from_generic_args (*generics, regions);
124 : 0 : if (mappings.is_error ())
125 : 0 : return;
126 : :
127 : 0 : concrete = type.handle_substitions (mappings);
128 : 0 : }
129 : :
130 : 0 : if (concrete != nullptr)
131 : 0 : resolved = concrete;
132 : : }
133 : :
134 : 33768 : SubstMapperInternal::SubstMapperInternal (
135 : 33768 : HirId ref, TyTy::SubstitutionArgumentMappings &mappings)
136 : 33768 : : resolved (new TyTy::ErrorType (ref)), mappings (mappings)
137 : 33768 : {}
138 : :
139 : : TyTy::BaseType *
140 : 33768 : SubstMapperInternal::Resolve (TyTy::BaseType *base,
141 : : TyTy::SubstitutionArgumentMappings &mappings)
142 : : {
143 : 33768 : auto context = TypeCheckContext::get ();
144 : :
145 : 33768 : SubstMapperInternal mapper (base->get_ref (), mappings);
146 : 33768 : base->accept_vis (mapper);
147 : 33768 : rust_assert (mapper.resolved != nullptr);
148 : :
149 : : // insert these new implict types into the context
150 : 33768 : TyTy::BaseType *unused = nullptr;
151 : 33768 : bool is_ty_available
152 : 33768 : = context->lookup_type (mapper.resolved->get_ty_ref (), &unused);
153 : 33768 : if (!is_ty_available)
154 : : {
155 : 10924 : context->insert_type (
156 : 10924 : Analysis::NodeMapping (0, 0, mapper.resolved->get_ty_ref (), 0),
157 : : mapper.resolved);
158 : : }
159 : 33768 : bool is_ref_available
160 : 33768 : = context->lookup_type (mapper.resolved->get_ref (), &unused);
161 : 33768 : if (!is_ref_available)
162 : : {
163 : 14526 : context->insert_type (Analysis::NodeMapping (0, 0,
164 : : mapper.resolved->get_ref (),
165 : 14526 : 0),
166 : : mapper.resolved);
167 : : }
168 : :
169 : 33768 : return mapper.resolved;
170 : : }
171 : :
172 : : bool
173 : 0 : SubstMapperInternal::mappings_are_bound (
174 : : TyTy::BaseType *tyseg, TyTy::SubstitutionArgumentMappings &mappings)
175 : : {
176 : 0 : if (tyseg->get_kind () == TyTy::TypeKind::ADT)
177 : : {
178 : 0 : TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (tyseg);
179 : 0 : return adt->are_mappings_bound (mappings);
180 : : }
181 : 0 : else if (tyseg->get_kind () == TyTy::TypeKind::FNDEF)
182 : : {
183 : 0 : TyTy::FnType *fn = static_cast<TyTy::FnType *> (tyseg);
184 : 0 : return fn->are_mappings_bound (mappings);
185 : : }
186 : :
187 : : return false;
188 : : }
189 : :
190 : : void
191 : 3069 : SubstMapperInternal::visit (TyTy::FnType &type)
192 : : {
193 : 3069 : TyTy::SubstitutionArgumentMappings adjusted
194 : 3069 : = type.adjust_mappings_for_this (mappings);
195 : 3069 : if (adjusted.is_error ())
196 : 0 : return;
197 : :
198 : 3069 : TyTy::BaseType *concrete = type.handle_substitions (adjusted);
199 : 3069 : if (concrete != nullptr)
200 : 3069 : resolved = concrete;
201 : 3069 : }
202 : :
203 : : void
204 : 1370 : SubstMapperInternal::visit (TyTy::ADTType &type)
205 : : {
206 : 1370 : TyTy::SubstitutionArgumentMappings adjusted
207 : 1370 : = type.adjust_mappings_for_this (mappings);
208 : 1370 : if (adjusted.is_error ())
209 : 0 : return;
210 : :
211 : 1370 : TyTy::BaseType *concrete = type.handle_substitions (adjusted);
212 : 1370 : if (concrete != nullptr)
213 : 1370 : resolved = concrete;
214 : 1370 : }
215 : :
216 : : // these don't support generic arguments but might contain a type param
217 : : void
218 : 168 : SubstMapperInternal::visit (TyTy::TupleType &type)
219 : : {
220 : 168 : resolved = type.handle_substitions (mappings);
221 : 168 : }
222 : :
223 : : void
224 : 3173 : SubstMapperInternal::visit (TyTy::ReferenceType &type)
225 : : {
226 : 3173 : resolved = type.handle_substitions (mappings);
227 : 3173 : }
228 : :
229 : : void
230 : 2074 : SubstMapperInternal::visit (TyTy::PointerType &type)
231 : : {
232 : 2074 : resolved = type.handle_substitions (mappings);
233 : 2074 : }
234 : :
235 : : void
236 : 21819 : SubstMapperInternal::visit (TyTy::ParamType &type)
237 : : {
238 : 21819 : resolved = type.handle_substitions (mappings);
239 : 21819 : }
240 : :
241 : : void
242 : 404 : SubstMapperInternal::visit (TyTy::PlaceholderType &type)
243 : : {
244 : 404 : rust_assert (type.can_resolve ());
245 : 404 : if (mappings.trait_item_mode ())
246 : : {
247 : 404 : resolved = type.resolve ();
248 : : }
249 : : else
250 : : {
251 : 0 : resolved = SubstMapperInternal::Resolve (type.resolve (), mappings);
252 : : }
253 : 404 : }
254 : :
255 : : void
256 : 564 : SubstMapperInternal::visit (TyTy::ProjectionType &type)
257 : : {
258 : 564 : resolved = type.handle_substitions (mappings);
259 : 564 : }
260 : :
261 : : void
262 : 0 : SubstMapperInternal::visit (TyTy::ClosureType &type)
263 : : {
264 : 0 : resolved = type.handle_substitions (mappings);
265 : 0 : }
266 : :
267 : : void
268 : 0 : SubstMapperInternal::visit (TyTy::ArrayType &type)
269 : : {
270 : 0 : resolved = type.handle_substitions (mappings);
271 : 0 : }
272 : :
273 : : void
274 : 1070 : SubstMapperInternal::visit (TyTy::SliceType &type)
275 : : {
276 : 1070 : resolved = type.handle_substitions (mappings);
277 : 1070 : }
278 : :
279 : : // nothing to do for these
280 : : void
281 : 0 : SubstMapperInternal::visit (TyTy::InferType &type)
282 : : {
283 : 0 : resolved = type.clone ();
284 : 0 : }
285 : : void
286 : 1 : SubstMapperInternal::visit (TyTy::FnPtr &type)
287 : : {
288 : 1 : resolved = type.clone ();
289 : 1 : }
290 : : void
291 : 0 : SubstMapperInternal::visit (TyTy::BoolType &type)
292 : : {
293 : 0 : resolved = type.clone ();
294 : 0 : }
295 : : void
296 : 0 : SubstMapperInternal::visit (TyTy::IntType &type)
297 : : {
298 : 0 : resolved = type.clone ();
299 : 0 : }
300 : : void
301 : 0 : SubstMapperInternal::visit (TyTy::UintType &type)
302 : : {
303 : 0 : resolved = type.clone ();
304 : 0 : }
305 : : void
306 : 0 : SubstMapperInternal::visit (TyTy::FloatType &type)
307 : : {
308 : 0 : resolved = type.clone ();
309 : 0 : }
310 : : void
311 : 0 : SubstMapperInternal::visit (TyTy::USizeType &type)
312 : : {
313 : 0 : resolved = type.clone ();
314 : 0 : }
315 : : void
316 : 56 : SubstMapperInternal::visit (TyTy::ISizeType &type)
317 : : {
318 : 56 : resolved = type.clone ();
319 : 56 : }
320 : : void
321 : 0 : SubstMapperInternal::visit (TyTy::ErrorType &type)
322 : : {
323 : 0 : resolved = type.clone ();
324 : 0 : }
325 : : void
326 : 0 : SubstMapperInternal::visit (TyTy::CharType &type)
327 : : {
328 : 0 : resolved = type.clone ();
329 : 0 : }
330 : : void
331 : 0 : SubstMapperInternal::visit (TyTy::StrType &type)
332 : : {
333 : 0 : resolved = type.clone ();
334 : 0 : }
335 : : void
336 : 0 : SubstMapperInternal::visit (TyTy::NeverType &type)
337 : : {
338 : 0 : resolved = type.clone ();
339 : 0 : }
340 : : void
341 : 0 : SubstMapperInternal::visit (TyTy::DynamicObjectType &type)
342 : : {
343 : 0 : resolved = type.clone ();
344 : 0 : }
345 : :
346 : : // SubstMapperFromExisting
347 : :
348 : 0 : SubstMapperFromExisting::SubstMapperFromExisting (TyTy::BaseType *concrete,
349 : 0 : TyTy::BaseType *receiver)
350 : 0 : : concrete (concrete), receiver (receiver), resolved (nullptr)
351 : 0 : {}
352 : :
353 : : TyTy::BaseType *
354 : 0 : SubstMapperFromExisting::Resolve (TyTy::BaseType *concrete,
355 : : TyTy::BaseType *receiver)
356 : : {
357 : 0 : rust_assert (concrete->get_kind () == receiver->get_kind ());
358 : :
359 : 0 : SubstMapperFromExisting mapper (concrete, receiver);
360 : 0 : concrete->accept_vis (mapper);
361 : 0 : return mapper.resolved;
362 : : }
363 : :
364 : : void
365 : 0 : SubstMapperFromExisting::visit (TyTy::FnType &type)
366 : : {
367 : 0 : rust_assert (type.was_substituted ());
368 : :
369 : 0 : TyTy::FnType *to_sub = static_cast<TyTy::FnType *> (receiver);
370 : 0 : resolved = to_sub->handle_substitions (type.get_substitution_arguments ());
371 : 0 : }
372 : :
373 : : void
374 : 0 : SubstMapperFromExisting::visit (TyTy::ADTType &type)
375 : : {
376 : 0 : rust_assert (type.was_substituted ());
377 : :
378 : 0 : TyTy::ADTType *to_sub = static_cast<TyTy::ADTType *> (receiver);
379 : 0 : resolved = to_sub->handle_substitions (type.get_substitution_arguments ());
380 : 0 : }
381 : :
382 : : void
383 : 0 : SubstMapperFromExisting::visit (TyTy::ClosureType &type)
384 : : {
385 : 0 : rust_assert (type.was_substituted ());
386 : :
387 : 0 : TyTy::ClosureType *to_sub = static_cast<TyTy::ClosureType *> (receiver);
388 : 0 : resolved = to_sub->handle_substitions (type.get_substitution_arguments ());
389 : 0 : }
390 : :
391 : : // GetUsedSubstArgs
392 : :
393 : 12368 : GetUsedSubstArgs::GetUsedSubstArgs ()
394 : 12368 : : args (TyTy::SubstitutionArgumentMappings::error ())
395 : 12368 : {}
396 : :
397 : : TyTy::SubstitutionArgumentMappings
398 : 12368 : GetUsedSubstArgs::From (const TyTy::BaseType *from)
399 : : {
400 : 12368 : GetUsedSubstArgs mapper;
401 : 12368 : from->accept_vis (mapper);
402 : 12368 : return mapper.args;
403 : 12368 : }
404 : :
405 : : void
406 : 0 : GetUsedSubstArgs::visit (const TyTy::FnType &type)
407 : : {
408 : 0 : args = type.get_substitution_arguments ();
409 : 0 : }
410 : :
411 : : void
412 : 4115 : GetUsedSubstArgs::visit (const TyTy::ADTType &type)
413 : : {
414 : 4115 : args = type.get_substitution_arguments ();
415 : 4115 : }
416 : :
417 : : void
418 : 0 : GetUsedSubstArgs::visit (const TyTy::ClosureType &type)
419 : : {
420 : 0 : args = type.get_substitution_arguments ();
421 : 0 : }
422 : :
423 : : } // namespace Resolver
424 : : } // namespace Rust
|