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-diagnostics.h"
20 : : #include "rust-hir-map.h"
21 : : #include "rust-hir-path.h"
22 : : #include "rust-hir-type-check-expr.h"
23 : : #include "rust-hir-type-check-type.h"
24 : : #include "rust-hir-type-check-item.h"
25 : : #include "rust-hir-trait-resolve.h"
26 : : #include "rust-substitution-mapper.h"
27 : : #include "rust-hir-path-probe.h"
28 : : #include "rust-type-util.h"
29 : : #include "rust-hir-type-bounds.h"
30 : : #include "rust-hir-item.h"
31 : : #include "rust-session-manager.h"
32 : : #include "rust-immutable-name-resolution-context.h"
33 : :
34 : : namespace Rust {
35 : : namespace Resolver {
36 : :
37 : : void
38 : 131 : TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
39 : : {
40 : 131 : HIR::QualifiedPathType qual_path_type = expr.get_path_type ();
41 : 131 : TyTy::BaseType *root = TypeCheckType::Resolve (qual_path_type.get_type ());
42 : 131 : if (root->get_kind () == TyTy::TypeKind::ERROR)
43 : : return;
44 : :
45 : 131 : if (!qual_path_type.has_as_clause ())
46 : : {
47 : 40 : NodeId root_resolved_node_id = UNKNOWN_NODEID;
48 : 40 : resolve_segments (root_resolved_node_id, expr.get_segments (), 0, root,
49 : : expr.get_mappings (), expr.get_locus ());
50 : 40 : return;
51 : : }
52 : :
53 : : // Resolve the trait now
54 : 91 : HIR::TypePath &trait_path_ref = qual_path_type.get_trait ();
55 : 91 : TraitReference *trait_ref = TraitResolver::Resolve (trait_path_ref);
56 : 91 : if (trait_ref->is_error ())
57 : : return;
58 : :
59 : : // does this type actually implement this type-bound?
60 : 91 : if (!TypeBoundsProbe::is_bound_satisfied_for_type (root, trait_ref))
61 : : return;
62 : :
63 : : // then we need to look at the next segment to create perform the correct
64 : : // projection type
65 : 91 : if (expr.get_segments ().empty ())
66 : : return;
67 : :
68 : : // get the predicate for the bound
69 : 91 : auto specified_bound
70 : 91 : = get_predicate_from_bound (trait_path_ref, qual_path_type.get_type ());
71 : 91 : if (specified_bound.is_error ())
72 : : return;
73 : :
74 : : // inherit the bound
75 : 182 : root->inherit_bounds ({specified_bound});
76 : :
77 : : // lookup the associated item from the specified bound
78 : 91 : HIR::PathExprSegment &item_seg = expr.get_segments ().at (0);
79 : 91 : HIR::PathIdentSegment item_seg_identifier = item_seg.get_segment ();
80 : 91 : TyTy::TypeBoundPredicateItem item
81 : 91 : = specified_bound.lookup_associated_item (item_seg_identifier.as_string ());
82 : 91 : if (item.is_error ())
83 : : {
84 : 0 : rust_error_at (item_seg.get_locus (), "unknown associated item");
85 : 0 : return;
86 : : }
87 : :
88 : : // we try to look for the real impl item if possible
89 : 91 : HIR::ImplItem *impl_item = nullptr;
90 : :
91 : : // lookup the associated impl trait for this if we can (it might be generic)
92 : 91 : AssociatedImplTrait *associated_impl_trait
93 : 91 : = lookup_associated_impl_block (specified_bound, root);
94 : 91 : if (associated_impl_trait != nullptr)
95 : : {
96 : 63 : associated_impl_trait->setup_associated_types (root, specified_bound);
97 : :
98 : 89 : for (auto &i :
99 : 89 : associated_impl_trait->get_impl_block ()->get_impl_items ())
100 : : {
101 : 47 : bool found = i->get_impl_item_name ().compare (
102 : 47 : item_seg_identifier.as_string ())
103 : 47 : == 0;
104 : 47 : if (found)
105 : : {
106 : 21 : impl_item = i.get ();
107 : 21 : break;
108 : : }
109 : : }
110 : : }
111 : :
112 : 133 : NodeId root_resolved_node_id = UNKNOWN_NODEID;
113 : 63 : if (impl_item == nullptr)
114 : : {
115 : : // this may be valid as there could be a default trait implementation here
116 : : // and we dont need to worry if the trait item is actually implemented or
117 : : // not because this will have already been validated as part of the trait
118 : : // impl block
119 : 70 : infered = item.get_tyty_for_receiver (root);
120 : 70 : root_resolved_node_id
121 : 70 : = item.get_raw_item ()->get_mappings ().get_nodeid ();
122 : : }
123 : : else
124 : : {
125 : 21 : HirId impl_item_id = impl_item->get_impl_mappings ().get_hirid ();
126 : 21 : bool ok = query_type (impl_item_id, &infered);
127 : 21 : if (!ok)
128 : : {
129 : : // FIXME
130 : : // I think query_type should error if required here anyway
131 : : return;
132 : : }
133 : :
134 : 21 : root_resolved_node_id = impl_item->get_impl_mappings ().get_nodeid ();
135 : : }
136 : :
137 : : // turbo-fish segment path::<ty>
138 : 91 : if (item_seg.has_generic_args ())
139 : : {
140 : 0 : if (!infered->has_substitutions_defined ())
141 : : {
142 : 0 : rust_error_at (item_seg.get_locus (),
143 : : "substitutions not supported for %s",
144 : 0 : infered->as_string ().c_str ());
145 : 0 : infered = new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
146 : 0 : return;
147 : : }
148 : 0 : std::vector<TyTy::Region> regions;
149 : :
150 : 0 : infered = SubstMapper::Resolve (infered, expr.get_locus (),
151 : 0 : &item_seg.get_generic_args (),
152 : 0 : context->regions_from_generic_args (
153 : 0 : item_seg.get_generic_args ()));
154 : 0 : }
155 : :
156 : : // continue on as a path-in-expression
157 : 91 : bool fully_resolved = expr.get_segments ().size () <= 1;
158 : 91 : if (fully_resolved)
159 : : {
160 : 91 : if (flag_name_resolution_2_0)
161 : : {
162 : 11 : auto &nr_ctx = const_cast<Resolver2_0::NameResolutionContext &> (
163 : 11 : Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
164 : :
165 : 11 : nr_ctx.map_usage (Resolver2_0::Usage (
166 : 11 : expr.get_mappings ().get_nodeid ()),
167 : 11 : Resolver2_0::Definition (root_resolved_node_id));
168 : : }
169 : : else
170 : : {
171 : 80 : resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
172 : : root_resolved_node_id);
173 : : }
174 : 91 : return;
175 : : }
176 : :
177 : 0 : resolve_segments (root_resolved_node_id, expr.get_segments (), 1, infered,
178 : : expr.get_mappings (), expr.get_locus ());
179 : 222 : }
180 : :
181 : : void
182 : 37520 : TypeCheckExpr::visit (HIR::PathInExpression &expr)
183 : : {
184 : 37520 : NodeId resolved_node_id = UNKNOWN_NODEID;
185 : 37520 : if (expr.is_lang_item ())
186 : : {
187 : 96 : auto lookup
188 : 96 : = Analysis::Mappings::get ().get_lang_item_node (expr.get_lang_item ());
189 : 96 : auto hir_id = mappings.lookup_node_to_hir (lookup);
190 : :
191 : : // We can type resolve the path in expression easily as it is a lang
192 : : // item path, but we still need to setup the various generics and
193 : : // substitutions
194 : :
195 : : // FIXME: We probably need to check *if* the type needs substitutions
196 : : // or not
197 : 96 : if (LangItem::IsEnumVariant (expr.get_lang_item ()))
198 : : {
199 : 60 : std::pair<HIR::Enum *, HIR::EnumItem *> enum_item_lookup
200 : 60 : = mappings.lookup_hir_enumitem (*hir_id);
201 : 120 : bool enum_item_ok = enum_item_lookup.first != nullptr
202 : 60 : && enum_item_lookup.second != nullptr;
203 : 0 : rust_assert (enum_item_ok);
204 : :
205 : 60 : HirId variant_id
206 : 60 : = enum_item_lookup.second->get_mappings ().get_hirid ();
207 : :
208 : 60 : HIR::EnumItem *enum_item = enum_item_lookup.second;
209 : 60 : resolved_node_id = enum_item->get_mappings ().get_nodeid ();
210 : :
211 : : // insert the id of the variant we are resolved to
212 : 60 : context->insert_variant_definition (expr.get_mappings ().get_hirid (),
213 : : variant_id);
214 : :
215 : 60 : query_type (variant_id, &infered);
216 : 60 : infered = SubstMapper::InferSubst (infered, expr.get_locus ());
217 : : }
218 : : else
219 : : {
220 : 36 : TyTy::BaseType *resolved = nullptr;
221 : 36 : context->lookup_type (*hir_id, &resolved);
222 : :
223 : 36 : rust_assert (resolved);
224 : :
225 : 36 : query_type (*hir_id, &infered);
226 : :
227 : 36 : infered = SubstMapper::InferSubst (resolved, expr.get_locus ());
228 : : }
229 : :
230 : : // FIXME: also we probably need to insert resolved types in the name
231 : : // resolver here
232 : : }
233 : : else
234 : : {
235 : 37424 : size_t offset = -1;
236 : 37424 : TyTy::BaseType *tyseg
237 : 37424 : = resolve_root_path (expr, &offset, &resolved_node_id);
238 : 37424 : if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
239 : 36062 : return;
240 : :
241 : 37406 : bool fully_resolved = offset == expr.get_segments ().size ();
242 : 37406 : if (fully_resolved)
243 : : {
244 : 36044 : infered = tyseg;
245 : 36044 : return;
246 : : }
247 : :
248 : 1362 : resolve_segments (resolved_node_id, expr.get_segments (), offset, tyseg,
249 : : expr.get_mappings (), expr.get_locus ());
250 : : }
251 : : }
252 : :
253 : : TyTy::BaseType *
254 : 37424 : TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
255 : : NodeId *root_resolved_node_id)
256 : : {
257 : 37424 : TyTy::BaseType *root_tyty = nullptr;
258 : 37424 : *offset = 0;
259 : 79350 : for (size_t i = 0; i < expr.get_num_segments (); i++)
260 : : {
261 : 43304 : HIR::PathExprSegment &seg = expr.get_segments ().at (i);
262 : :
263 : 43304 : bool have_more_segments = (expr.get_num_segments () - 1 != i);
264 : 43304 : bool is_root = *offset == 0;
265 : 43304 : NodeId ast_node_id = seg.get_mappings ().get_nodeid ();
266 : :
267 : : // then lookup the reference_node_id
268 : 43304 : NodeId ref_node_id = UNKNOWN_NODEID;
269 : :
270 : 43304 : if (flag_name_resolution_2_0)
271 : : {
272 : 5259 : auto &nr_ctx
273 : 5259 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
274 : :
275 : : // assign the ref_node_id if we've found something
276 : 5259 : nr_ctx.lookup (ast_node_id).map ([&ref_node_id] (NodeId resolved) {
277 : 4983 : ref_node_id = resolved;
278 : : });
279 : : }
280 : 38045 : else if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
281 : 6803 : resolver->lookup_resolved_type (ast_node_id, &ref_node_id);
282 : :
283 : : // ref_node_id is the NodeId that the segments refers to.
284 : 43304 : if (ref_node_id == UNKNOWN_NODEID)
285 : : {
286 : 1366 : if (root_tyty != nullptr && *offset > 0)
287 : : {
288 : : // then we can let the impl path probe take over now
289 : 1378 : return root_tyty;
290 : : }
291 : :
292 : 4 : rust_error_at (seg.get_locus (),
293 : : "failed to type resolve root segment");
294 : 4 : return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
295 : : }
296 : :
297 : : // node back to HIR
298 : 41938 : tl::optional<HirId> hid = mappings.lookup_node_to_hir (ref_node_id);
299 : 41938 : if (!hid.has_value ())
300 : : {
301 : 0 : rust_error_at (seg.get_locus (), "456 reverse lookup failure");
302 : 0 : rust_debug_loc (seg.get_locus (),
303 : : "failure with [%s] mappings [%s] ref_node_id [%u]",
304 : 0 : seg.as_string ().c_str (),
305 : 0 : seg.get_mappings ().as_string ().c_str (),
306 : : ref_node_id);
307 : :
308 : 0 : return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
309 : : }
310 : 41938 : auto ref = hid.value ();
311 : :
312 : 41938 : auto seg_is_module = mappings.lookup_module (ref).has_value ();
313 : 41938 : auto seg_is_crate = mappings.is_local_hirid_crate (ref);
314 : 41938 : auto seg_is_pattern = mappings.lookup_hir_pattern (ref).has_value ();
315 : 41938 : auto seg_is_self = is_root && !have_more_segments
316 : 74144 : && seg.get_segment ().as_string () == "self";
317 : 41938 : if (seg_is_module || seg_is_crate)
318 : : {
319 : : // A::B::C::this_is_a_module::D::E::F
320 : : // ^^^^^^^^^^^^^^^^
321 : : // Currently handling this.
322 : 2938 : if (have_more_segments)
323 : : {
324 : 2936 : (*offset)++;
325 : 2936 : continue;
326 : : }
327 : :
328 : : // In the case of :
329 : : // A::B::C::this_is_a_module
330 : : // ^^^^^^^^^^^^^^^^
331 : : // This is an error, we are not expecting a module.
332 : 2 : rust_error_at (seg.get_locus (), "expected value");
333 : 2 : return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
334 : : }
335 : :
336 : 39000 : TyTy::BaseType *lookup = nullptr;
337 : 39000 : if (!query_type (ref, &lookup))
338 : : {
339 : 6 : if (is_root || root_tyty == nullptr)
340 : : {
341 : 12 : rust_error_at (expr.get_locus (), ErrorCode::E0425,
342 : : "cannot find value %qs in this scope",
343 : 12 : expr.as_simple_path ().as_string ().c_str ());
344 : :
345 : 6 : return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
346 : : }
347 : : return root_tyty;
348 : : }
349 : :
350 : : // is it an enum item?
351 : 38994 : std::pair<HIR::Enum *, HIR::EnumItem *> enum_item_lookup
352 : 38994 : = mappings.lookup_hir_enumitem (ref);
353 : 79611 : bool is_enum_item = enum_item_lookup.first != nullptr
354 : 38994 : && enum_item_lookup.second != nullptr;
355 : 1623 : if (is_enum_item)
356 : : {
357 : 1623 : HirId expr_id = expr.get_mappings ().get_hirid ();
358 : 1623 : HirId variant_id
359 : 1623 : = enum_item_lookup.second->get_mappings ().get_hirid ();
360 : 1623 : context->insert_variant_definition (expr_id, variant_id);
361 : : }
362 : :
363 : : // if we have a previous segment type
364 : 38994 : if (root_tyty != nullptr)
365 : : {
366 : : // if this next segment needs substitution we must apply the
367 : : // previous type arguments
368 : : //
369 : : // such as: GenericStruct::<_>::new(123, 456)
370 : 1582 : if (lookup->needs_generic_substitutions ())
371 : : {
372 : 747 : if (!root_tyty->needs_generic_substitutions ())
373 : : {
374 : 747 : auto used_args_in_prev_segment
375 : 747 : = GetUsedSubstArgs::From (root_tyty);
376 : 747 : lookup
377 : 747 : = SubstMapperInternal::Resolve (lookup,
378 : : used_args_in_prev_segment);
379 : 747 : }
380 : : }
381 : : }
382 : :
383 : : // turbo-fish segment path::<ty>
384 : 38994 : if (seg.has_generic_args ())
385 : : {
386 : 870 : lookup = SubstMapper::Resolve (lookup, expr.get_locus (),
387 : 870 : &seg.get_generic_args (),
388 : 870 : context->regions_from_generic_args (
389 : 870 : seg.get_generic_args ()));
390 : 870 : if (lookup->get_kind () == TyTy::TypeKind::ERROR)
391 : 4 : return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
392 : : }
393 : 38124 : else if (lookup->needs_generic_substitutions () && !seg_is_pattern
394 : 38124 : && !seg_is_self)
395 : : {
396 : 3818 : lookup = SubstMapper::InferSubst (lookup, expr.get_locus ());
397 : : }
398 : :
399 : 38990 : *root_resolved_node_id = ref_node_id;
400 : 38990 : *offset = *offset + 1;
401 : 38990 : root_tyty = lookup;
402 : : }
403 : :
404 : : return root_tyty;
405 : : }
406 : :
407 : : void
408 : 1402 : TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
409 : : std::vector<HIR::PathExprSegment> &segments,
410 : : size_t offset, TyTy::BaseType *tyseg,
411 : : const Analysis::NodeMapping &expr_mappings,
412 : : location_t expr_locus)
413 : : {
414 : 1402 : NodeId resolved_node_id = root_resolved_node_id;
415 : 1402 : TyTy::BaseType *prev_segment = tyseg;
416 : 1402 : bool receiver_is_generic = prev_segment->get_kind () == TyTy::TypeKind::PARAM;
417 : 1402 : bool receiver_is_dyn = prev_segment->get_kind () == TyTy::TypeKind::DYNAMIC;
418 : :
419 : 2800 : for (size_t i = offset; i < segments.size (); i++)
420 : : {
421 : 1402 : HIR::PathExprSegment &seg = segments.at (i);
422 : 1402 : bool probe_impls = !receiver_is_generic;
423 : :
424 : : // probe the path is done in two parts one where we search impls if no
425 : : // candidate is found then we search extensions from traits
426 : 1402 : auto candidates
427 : 1402 : = PathProbeType::Probe (prev_segment, seg.get_segment (), probe_impls,
428 : : false /*probe_bounds*/,
429 : 1402 : true /*ignore_mandatory_trait_items*/);
430 : 1402 : if (candidates.size () == 0)
431 : : {
432 : 377 : candidates
433 : 377 : = PathProbeType::Probe (prev_segment, seg.get_segment (), false,
434 : : true /*probe_bounds*/,
435 : 377 : false /*ignore_mandatory_trait_items*/);
436 : :
437 : 377 : if (candidates.size () == 0)
438 : : {
439 : 0 : rust_error_at (
440 : : seg.get_locus (),
441 : : "failed to resolve path segment using an impl Probe");
442 : 0 : return;
443 : : }
444 : : }
445 : :
446 : 1402 : if (candidates.size () > 1)
447 : : {
448 : 2 : ReportMultipleCandidateError::Report (candidates, seg.get_segment (),
449 : : seg.get_locus ());
450 : 2 : return;
451 : : }
452 : :
453 : 1400 : auto &candidate = *candidates.begin ();
454 : 1400 : prev_segment = tyseg;
455 : 1400 : tyseg = candidate.ty;
456 : :
457 : 1400 : HIR::ImplBlock *associated_impl_block = nullptr;
458 : 1400 : if (candidate.is_enum_candidate ())
459 : : {
460 : 67 : const TyTy::VariantDef *variant = candidate.item.enum_field.variant;
461 : :
462 : 67 : HirId variant_id = variant->get_id ();
463 : 67 : std::pair<HIR::Enum *, HIR::EnumItem *> enum_item_lookup
464 : 67 : = mappings.lookup_hir_enumitem (variant_id);
465 : 134 : bool enum_item_ok = enum_item_lookup.first != nullptr
466 : 67 : && enum_item_lookup.second != nullptr;
467 : 0 : rust_assert (enum_item_ok);
468 : :
469 : 67 : HIR::EnumItem *enum_item = enum_item_lookup.second;
470 : 67 : resolved_node_id = enum_item->get_mappings ().get_nodeid ();
471 : :
472 : : // insert the id of the variant we are resolved to
473 : 67 : context->insert_variant_definition (expr_mappings.get_hirid (),
474 : : variant_id);
475 : : }
476 : 1333 : else if (candidate.is_impl_candidate ())
477 : : {
478 : 956 : resolved_node_id
479 : 956 : = candidate.item.impl.impl_item->get_impl_mappings ().get_nodeid ();
480 : :
481 : 956 : associated_impl_block = candidate.item.impl.parent;
482 : : }
483 : : else
484 : : {
485 : 377 : resolved_node_id
486 : 377 : = candidate.item.trait.item_ref->get_mappings ().get_nodeid ();
487 : :
488 : : // lookup the associated-impl-trait
489 : 377 : HIR::ImplBlock *impl = candidate.item.trait.impl;
490 : 377 : if (impl != nullptr)
491 : : {
492 : : // get the associated impl block
493 : : associated_impl_block = impl;
494 : : }
495 : : }
496 : :
497 : 1400 : if (associated_impl_block != nullptr && !receiver_is_dyn)
498 : : {
499 : : // associated types
500 : 1008 : HirId impl_block_id
501 : 1008 : = associated_impl_block->get_mappings ().get_hirid ();
502 : :
503 : 1008 : AssociatedImplTrait *associated = nullptr;
504 : 1008 : bool found_impl_trait
505 : 1008 : = context->lookup_associated_trait_impl (impl_block_id,
506 : : &associated);
507 : :
508 : 1008 : auto mappings = TyTy::SubstitutionArgumentMappings::error ();
509 : 1008 : TyTy::BaseType *impl_block_ty
510 : 1008 : = TypeCheckItem::ResolveImplBlockSelfWithInference (
511 : : *associated_impl_block, seg.get_locus (), &mappings);
512 : :
513 : : // we need to apply the arguments to the segment type so they get
514 : : // unified properly
515 : 1008 : if (!mappings.is_error ())
516 : 153 : tyseg = SubstMapperInternal::Resolve (tyseg, mappings);
517 : :
518 : 2016 : prev_segment = unify_site (seg.get_mappings ().get_hirid (),
519 : 1008 : TyTy::TyWithLocation (prev_segment),
520 : 1008 : TyTy::TyWithLocation (impl_block_ty),
521 : : seg.get_locus ());
522 : 1008 : bool ok = prev_segment->get_kind () != TyTy::TypeKind::ERROR;
523 : 1008 : if (!ok)
524 : 2 : return;
525 : :
526 : 1006 : if (found_impl_trait)
527 : : {
528 : : // we need to setup with apropriate bounds
529 : 188 : HIR::TypePath &bound_path
530 : 188 : = associated->get_impl_block ()->get_trait_ref ();
531 : 188 : const auto &trait_ref = *TraitResolver::Resolve (bound_path);
532 : 188 : rust_assert (!trait_ref.is_error ());
533 : :
534 : 188 : const auto &predicate
535 : 188 : = impl_block_ty->lookup_predicate (trait_ref.get_defid ());
536 : 188 : if (!predicate.is_error ())
537 : 170 : impl_block_ty
538 : 170 : = associated->setup_associated_types (prev_segment, predicate,
539 : : nullptr, false);
540 : 188 : }
541 : 1008 : }
542 : :
543 : 1398 : if (seg.has_generic_args ())
544 : : {
545 : 56 : rust_debug_loc (seg.get_locus (), "applying segment generics: %s",
546 : 56 : tyseg->as_string ().c_str ());
547 : 56 : tyseg
548 : 56 : = SubstMapper::Resolve (tyseg, expr_locus, &seg.get_generic_args (),
549 : 56 : context->regions_from_generic_args (
550 : 56 : seg.get_generic_args ()));
551 : 56 : if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
552 : : return;
553 : : }
554 : 1342 : else if (tyseg->needs_generic_substitutions () && !receiver_is_generic)
555 : : {
556 : 296 : location_t locus = seg.get_locus ();
557 : 296 : tyseg = SubstMapper::InferSubst (tyseg, locus);
558 : 296 : if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
559 : : return;
560 : : }
561 : 1402 : }
562 : :
563 : 1398 : rust_assert (resolved_node_id != UNKNOWN_NODEID);
564 : 1398 : if (flag_name_resolution_2_0)
565 : : {
566 : 278 : auto &nr_ctx = const_cast<Resolver2_0::NameResolutionContext &> (
567 : 278 : Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
568 : :
569 : 278 : nr_ctx.map_usage (Resolver2_0::Usage (expr_mappings.get_nodeid ()),
570 : 278 : Resolver2_0::Definition (resolved_node_id));
571 : : }
572 : : // name scope first
573 : 1120 : else if (resolver->get_name_scope ().decl_was_declared_here (
574 : : resolved_node_id))
575 : : {
576 : 1114 : resolver->insert_resolved_name (expr_mappings.get_nodeid (),
577 : : resolved_node_id);
578 : : }
579 : : // check the type scope
580 : 6 : else if (resolver->get_type_scope ().decl_was_declared_here (
581 : : resolved_node_id))
582 : : {
583 : 0 : resolver->insert_resolved_type (expr_mappings.get_nodeid (),
584 : : resolved_node_id);
585 : : }
586 : : else
587 : : {
588 : 6 : resolver->insert_resolved_misc (expr_mappings.get_nodeid (),
589 : : resolved_node_id);
590 : : }
591 : :
592 : 1398 : infered = tyseg;
593 : : }
594 : :
595 : : } // namespace Resolver
596 : : } // namespace Rust
|