[PR testsuite/116860] Testsuite adjustment for recently added tests
[official-gcc.git] / gcc / rust / typecheck / rust-substitution-mapper.cc
blobdbf49bef5b764ad796b1fcbc35409e7c7e8b0e6a
1 // Copyright (C) 2020-2025 Free Software Foundation, Inc.
3 // This file is part of GCC.
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.
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.
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/>.
19 #include "rust-substitution-mapper.h"
20 #include "rust-hir-type-check.h"
22 namespace Rust {
23 namespace Resolver {
25 SubstMapper::SubstMapper (HirId ref, HIR::GenericArgs *generics,
26 const std::vector<TyTy::Region> &regions,
27 location_t locus)
28 : resolved (new TyTy::ErrorType (ref)), generics (generics),
29 regions (regions), locus (locus)
32 TyTy::BaseType *
33 SubstMapper::Resolve (TyTy::BaseType *base, location_t locus,
34 HIR::GenericArgs *generics,
35 const std::vector<TyTy::Region> &regions)
37 SubstMapper mapper (base->get_ref (), generics, regions, locus);
38 base->accept_vis (mapper);
39 rust_assert (mapper.resolved != nullptr);
40 return mapper.resolved;
43 TyTy::BaseType *
44 SubstMapper::InferSubst (TyTy::BaseType *base, location_t locus)
46 return SubstMapper::Resolve (base, locus, nullptr, {});
49 bool
50 SubstMapper::have_generic_args () const
52 return generics != nullptr;
55 void
56 SubstMapper::visit (TyTy::FnType &type)
58 TyTy::FnType *concrete = nullptr;
59 if (!have_generic_args ())
61 TyTy::BaseType *substs = type.infer_substitions (locus);
62 rust_assert (substs->get_kind () == TyTy::TypeKind::FNDEF);
63 concrete = static_cast<TyTy::FnType *> (substs);
65 else
67 TyTy::SubstitutionArgumentMappings mappings
68 = type.get_mappings_from_generic_args (*generics, regions);
69 if (mappings.is_error ())
70 return;
72 concrete = type.handle_substitions (mappings);
75 if (concrete != nullptr)
76 resolved = concrete;
79 void
80 SubstMapper::visit (TyTy::ADTType &type)
82 TyTy::ADTType *concrete = nullptr;
83 if (!have_generic_args ())
85 TyTy::BaseType *substs = type.infer_substitions (locus);
86 rust_assert (substs->get_kind () == TyTy::TypeKind::ADT);
87 concrete = static_cast<TyTy::ADTType *> (substs);
89 else
91 TyTy::SubstitutionArgumentMappings mappings
92 = type.get_mappings_from_generic_args (*generics, regions);
93 if (mappings.is_error ())
94 return;
96 concrete = type.handle_substitions (mappings);
99 if (concrete != nullptr)
100 resolved = concrete;
103 void
104 SubstMapper::visit (TyTy::PlaceholderType &type)
106 rust_assert (type.can_resolve ());
107 resolved = SubstMapper::Resolve (type.resolve (), locus, generics, regions);
110 void
111 SubstMapper::visit (TyTy::ProjectionType &type)
113 TyTy::ProjectionType *concrete = nullptr;
114 if (!have_generic_args ())
116 TyTy::BaseType *substs = type.infer_substitions (locus);
117 rust_assert (substs->get_kind () == TyTy::TypeKind::PROJECTION);
118 concrete = static_cast<TyTy::ProjectionType *> (substs);
120 else
122 TyTy::SubstitutionArgumentMappings mappings
123 = type.get_mappings_from_generic_args (*generics, regions);
124 if (mappings.is_error ())
125 return;
127 concrete = type.handle_substitions (mappings);
130 if (concrete != nullptr)
131 resolved = concrete;
134 SubstMapperInternal::SubstMapperInternal (
135 HirId ref, TyTy::SubstitutionArgumentMappings &mappings)
136 : resolved (new TyTy::ErrorType (ref)), mappings (mappings)
139 TyTy::BaseType *
140 SubstMapperInternal::Resolve (TyTy::BaseType *base,
141 TyTy::SubstitutionArgumentMappings &mappings)
143 auto context = TypeCheckContext::get ();
145 SubstMapperInternal mapper (base->get_ref (), mappings);
146 base->accept_vis (mapper);
147 rust_assert (mapper.resolved != nullptr);
149 // insert these new implict types into the context
150 TyTy::BaseType *unused = nullptr;
151 bool is_ty_available
152 = context->lookup_type (mapper.resolved->get_ty_ref (), &unused);
153 if (!is_ty_available)
155 context->insert_type (
156 Analysis::NodeMapping (0, 0, mapper.resolved->get_ty_ref (), 0),
157 mapper.resolved);
159 bool is_ref_available
160 = context->lookup_type (mapper.resolved->get_ref (), &unused);
161 if (!is_ref_available)
163 context->insert_type (Analysis::NodeMapping (0, 0,
164 mapper.resolved->get_ref (),
166 mapper.resolved);
169 return mapper.resolved;
172 bool
173 SubstMapperInternal::mappings_are_bound (
174 TyTy::BaseType *tyseg, TyTy::SubstitutionArgumentMappings &mappings)
176 if (tyseg->get_kind () == TyTy::TypeKind::ADT)
178 TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (tyseg);
179 return adt->are_mappings_bound (mappings);
181 else if (tyseg->get_kind () == TyTy::TypeKind::FNDEF)
183 TyTy::FnType *fn = static_cast<TyTy::FnType *> (tyseg);
184 return fn->are_mappings_bound (mappings);
187 return false;
190 void
191 SubstMapperInternal::visit (TyTy::FnType &type)
193 TyTy::SubstitutionArgumentMappings adjusted
194 = type.adjust_mappings_for_this (mappings);
195 if (adjusted.is_error ())
196 return;
198 TyTy::BaseType *concrete = type.handle_substitions (adjusted);
199 if (concrete != nullptr)
200 resolved = concrete;
203 void
204 SubstMapperInternal::visit (TyTy::ADTType &type)
206 TyTy::SubstitutionArgumentMappings adjusted
207 = type.adjust_mappings_for_this (mappings);
208 if (adjusted.is_error ())
209 return;
211 TyTy::BaseType *concrete = type.handle_substitions (adjusted);
212 if (concrete != nullptr)
213 resolved = concrete;
216 // these don't support generic arguments but might contain a type param
217 void
218 SubstMapperInternal::visit (TyTy::TupleType &type)
220 resolved = type.handle_substitions (mappings);
223 void
224 SubstMapperInternal::visit (TyTy::ReferenceType &type)
226 resolved = type.handle_substitions (mappings);
229 void
230 SubstMapperInternal::visit (TyTy::PointerType &type)
232 resolved = type.handle_substitions (mappings);
235 void
236 SubstMapperInternal::visit (TyTy::ParamType &type)
238 resolved = type.handle_substitions (mappings);
241 void
242 SubstMapperInternal::visit (TyTy::PlaceholderType &type)
244 rust_assert (type.can_resolve ());
245 if (mappings.trait_item_mode ())
247 resolved = type.resolve ();
249 else
251 resolved = SubstMapperInternal::Resolve (type.resolve (), mappings);
255 void
256 SubstMapperInternal::visit (TyTy::ProjectionType &type)
258 resolved = type.handle_substitions (mappings);
261 void
262 SubstMapperInternal::visit (TyTy::ClosureType &type)
264 resolved = type.handle_substitions (mappings);
267 void
268 SubstMapperInternal::visit (TyTy::ArrayType &type)
270 resolved = type.handle_substitions (mappings);
273 void
274 SubstMapperInternal::visit (TyTy::SliceType &type)
276 resolved = type.handle_substitions (mappings);
279 // nothing to do for these
280 void
281 SubstMapperInternal::visit (TyTy::InferType &type)
283 resolved = type.clone ();
285 void
286 SubstMapperInternal::visit (TyTy::FnPtr &type)
288 resolved = type.clone ();
290 void
291 SubstMapperInternal::visit (TyTy::BoolType &type)
293 resolved = type.clone ();
295 void
296 SubstMapperInternal::visit (TyTy::IntType &type)
298 resolved = type.clone ();
300 void
301 SubstMapperInternal::visit (TyTy::UintType &type)
303 resolved = type.clone ();
305 void
306 SubstMapperInternal::visit (TyTy::FloatType &type)
308 resolved = type.clone ();
310 void
311 SubstMapperInternal::visit (TyTy::USizeType &type)
313 resolved = type.clone ();
315 void
316 SubstMapperInternal::visit (TyTy::ISizeType &type)
318 resolved = type.clone ();
320 void
321 SubstMapperInternal::visit (TyTy::ErrorType &type)
323 resolved = type.clone ();
325 void
326 SubstMapperInternal::visit (TyTy::CharType &type)
328 resolved = type.clone ();
330 void
331 SubstMapperInternal::visit (TyTy::StrType &type)
333 resolved = type.clone ();
335 void
336 SubstMapperInternal::visit (TyTy::NeverType &type)
338 resolved = type.clone ();
340 void
341 SubstMapperInternal::visit (TyTy::DynamicObjectType &type)
343 resolved = type.clone ();
346 // SubstMapperFromExisting
348 SubstMapperFromExisting::SubstMapperFromExisting (TyTy::BaseType *concrete,
349 TyTy::BaseType *receiver)
350 : concrete (concrete), receiver (receiver), resolved (nullptr)
353 TyTy::BaseType *
354 SubstMapperFromExisting::Resolve (TyTy::BaseType *concrete,
355 TyTy::BaseType *receiver)
357 rust_assert (concrete->get_kind () == receiver->get_kind ());
359 SubstMapperFromExisting mapper (concrete, receiver);
360 concrete->accept_vis (mapper);
361 return mapper.resolved;
364 void
365 SubstMapperFromExisting::visit (TyTy::FnType &type)
367 rust_assert (type.was_substituted ());
369 TyTy::FnType *to_sub = static_cast<TyTy::FnType *> (receiver);
370 resolved = to_sub->handle_substitions (type.get_substitution_arguments ());
373 void
374 SubstMapperFromExisting::visit (TyTy::ADTType &type)
376 rust_assert (type.was_substituted ());
378 TyTy::ADTType *to_sub = static_cast<TyTy::ADTType *> (receiver);
379 resolved = to_sub->handle_substitions (type.get_substitution_arguments ());
382 void
383 SubstMapperFromExisting::visit (TyTy::ClosureType &type)
385 rust_assert (type.was_substituted ());
387 TyTy::ClosureType *to_sub = static_cast<TyTy::ClosureType *> (receiver);
388 resolved = to_sub->handle_substitions (type.get_substitution_arguments ());
391 // GetUsedSubstArgs
393 GetUsedSubstArgs::GetUsedSubstArgs ()
394 : args (TyTy::SubstitutionArgumentMappings::error ())
397 TyTy::SubstitutionArgumentMappings
398 GetUsedSubstArgs::From (const TyTy::BaseType *from)
400 GetUsedSubstArgs mapper;
401 from->accept_vis (mapper);
402 return mapper.args;
405 void
406 GetUsedSubstArgs::visit (const TyTy::FnType &type)
408 args = type.get_substitution_arguments ();
411 void
412 GetUsedSubstArgs::visit (const TyTy::ADTType &type)
414 args = type.get_substitution_arguments ();
417 void
418 GetUsedSubstArgs::visit (const TyTy::ClosureType &type)
420 args = type.get_substitution_arguments ();
423 } // namespace Resolver
424 } // namespace Rust