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 "optional.h"
20 : : #include "rust-ast-full.h"
21 : : #include "rust-diagnostics.h"
22 : : #include "rust-hir-map.h"
23 : : #include "rust-late-name-resolver-2.0.h"
24 : : #include "rust-default-resolver.h"
25 : : #include "rust-name-resolution-context.h"
26 : : #include "rust-path.h"
27 : : #include "rust-system.h"
28 : : #include "rust-tyty.h"
29 : : #include "rust-hir-type-check.h"
30 : : #include "rust-ice-finalizer.h"
31 : : #include "rust-ast.h"
32 : :
33 : : namespace Rust {
34 : : namespace Resolver2_0 {
35 : :
36 : 1002 : Late::Late (NameResolutionContext &ctx) : DefaultResolver (ctx) {}
37 : :
38 : : static NodeId
39 : 19038 : next_node_id ()
40 : : {
41 : 19038 : return Analysis::Mappings::get ().get_next_node_id ();
42 : : };
43 : :
44 : : static HirId
45 : 18036 : next_hir_id ()
46 : : {
47 : 18036 : return Analysis::Mappings::get ().get_next_hir_id ();
48 : : };
49 : :
50 : : void
51 : 1002 : Late::setup_builtin_types ()
52 : : {
53 : : // access the global type context to setup the TyTys
54 : 1002 : auto &ty_ctx = *Resolver::TypeCheckContext::get ();
55 : :
56 : : // Late builtin type struct helper
57 : 1002 : struct LType
58 : : {
59 : : std::string name;
60 : : NodeId node_id;
61 : : NodeId hir_id;
62 : : TyTy::BaseType *type;
63 : :
64 : 18036 : explicit LType (std::string name, TyTy::BaseType *type)
65 : 36072 : : name (name), node_id (next_node_id ()), hir_id (type->get_ref ()),
66 : 18036 : type (type)
67 : 18036 : {}
68 : : };
69 : :
70 : 1002 : static const LType builtins[] = {
71 : 2004 : {LType ("bool", new TyTy::BoolType (next_hir_id ()))},
72 : 2004 : {LType ("u8", new TyTy::UintType (next_hir_id (), TyTy::UintType::U8))},
73 : 2004 : {LType ("u16", new TyTy::UintType (next_hir_id (), TyTy::UintType::U16))},
74 : 2004 : {LType ("u32", new TyTy::UintType (next_hir_id (), TyTy::UintType::U32))},
75 : 2004 : {LType ("u64", new TyTy::UintType (next_hir_id (), TyTy::UintType::U64))},
76 : 2004 : {LType ("u128", new TyTy::UintType (next_hir_id (), TyTy::UintType::U128))},
77 : 2004 : {LType ("i8", new TyTy::IntType (next_hir_id (), TyTy::IntType::I8))},
78 : 2004 : {LType ("i16", new TyTy::IntType (next_hir_id (), TyTy::IntType::I16))},
79 : 2004 : {LType ("i32", new TyTy::IntType (next_hir_id (), TyTy::IntType::I32))},
80 : 2004 : {LType ("i64", new TyTy::IntType (next_hir_id (), TyTy::IntType::I64))},
81 : 2004 : {LType ("i128", new TyTy::IntType (next_hir_id (), TyTy::IntType::I128))},
82 : 2004 : {LType ("f32", new TyTy::FloatType (next_hir_id (), TyTy::FloatType::F32))},
83 : 2004 : {LType ("f64", new TyTy::FloatType (next_hir_id (), TyTy::FloatType::F64))},
84 : 2004 : {LType ("usize", new TyTy::USizeType (next_hir_id ()))},
85 : 2004 : {LType ("isize", new TyTy::ISizeType (next_hir_id ()))},
86 : 2004 : {LType ("char", new TyTy::CharType (next_hir_id ()))},
87 : 2004 : {LType ("str", new TyTy::StrType (next_hir_id ()))},
88 : 2004 : {LType ("!", new TyTy::NeverType (next_hir_id ()))},
89 : :
90 : : // the unit type `()` does not play a part in name-resolution - so we only
91 : : // insert it in the type context...
92 : 20040 : };
93 : :
94 : : // There's a special Rib for putting prelude items, since prelude items need
95 : : // to satisfy certain special rules.
96 : 1002 : ctx.scoped (Rib::Kind::Prelude, 0, [this, &ty_ctx] (void) -> void {
97 : 19038 : for (const auto &builtin : builtins)
98 : : {
99 : 54108 : auto ok = ctx.types.insert (builtin.name, builtin.node_id);
100 : 18036 : rust_assert (ok);
101 : :
102 : 18036 : ctx.mappings.insert_node_to_hir (builtin.node_id, builtin.hir_id);
103 : 18036 : ty_ctx.insert_builtin (builtin.hir_id, builtin.node_id, builtin.type);
104 : 18036 : }
105 : 1002 : });
106 : :
107 : : // ...here!
108 : 1002 : auto *unit_type = TyTy::TupleType::get_unit_type ();
109 : 1002 : ty_ctx.insert_builtin (unit_type->get_ref (), next_node_id (), unit_type);
110 : 1002 : }
111 : :
112 : : void
113 : 1002 : Late::go (AST::Crate &crate)
114 : : {
115 : 1002 : setup_builtin_types ();
116 : :
117 : 4250 : for (auto &item : crate.items)
118 : 3251 : item->accept_vis (*this);
119 : 999 : }
120 : :
121 : : void
122 : 0 : Late::new_label (Identifier name, NodeId id)
123 : : {
124 : : // labels can always shadow, so `insert` should never fail. if it does, we're
125 : : // in big trouble!
126 : 0 : auto ok = ctx.labels.insert (name, id);
127 : :
128 : 0 : rust_assert (ok);
129 : 0 : }
130 : :
131 : : void
132 : 0 : Late::visit (AST::ForLoopExpr &expr)
133 : : {
134 : 0 : visit_outer_attrs (expr);
135 : :
136 : 0 : ctx.bindings.enter (BindingSource::For);
137 : :
138 : 0 : visit (expr.get_pattern ());
139 : :
140 : 0 : ctx.bindings.exit ();
141 : :
142 : 0 : visit (expr.get_iterator_expr ());
143 : 0 : visit (expr.get_loop_label ());
144 : 0 : visit (expr.get_loop_block ());
145 : 0 : }
146 : :
147 : : void
148 : 6 : Late::visit (AST::IfLetExpr &expr)
149 : : {
150 : 6 : visit_outer_attrs (expr);
151 : :
152 : 6 : ctx.bindings.enter (BindingSource::Let);
153 : :
154 : 12 : for (auto &pattern : expr.get_patterns ())
155 : 6 : visit (pattern);
156 : :
157 : 6 : ctx.bindings.exit ();
158 : :
159 : 6 : visit (expr.get_value_expr ());
160 : 6 : visit (expr.get_if_block ());
161 : 6 : }
162 : :
163 : : void
164 : 140 : Late::visit (AST::MatchArm &arm)
165 : : {
166 : 140 : visit_outer_attrs (arm);
167 : :
168 : 140 : ctx.bindings.enter (BindingSource::Match);
169 : :
170 : 280 : for (auto &pattern : arm.get_patterns ())
171 : 140 : visit (pattern);
172 : :
173 : 140 : ctx.bindings.exit ();
174 : :
175 : 140 : if (arm.has_match_arm_guard ())
176 : 1 : visit (arm.get_guard_expr ());
177 : 140 : }
178 : :
179 : : void
180 : 1418 : Late::visit (AST::LetStmt &let)
181 : : {
182 : 1418 : DefaultASTVisitor::visit_outer_attrs (let);
183 : 1418 : if (let.has_type ())
184 : 368 : visit (let.get_type ());
185 : : // visit expression before pattern
186 : : // this makes variable shadowing work properly
187 : 1418 : if (let.has_init_expr ())
188 : 1247 : visit (let.get_init_expr ());
189 : :
190 : 1418 : ctx.bindings.enter (BindingSource::Let);
191 : :
192 : 1418 : visit (let.get_pattern ());
193 : :
194 : 1418 : ctx.bindings.exit ();
195 : :
196 : 1418 : if (let.has_else_expr ())
197 : 0 : visit (let.get_init_expr ());
198 : :
199 : : // how do we deal with the fact that `let a = blipbloup` should look for a
200 : : // label and cannot go through function ribs, but `let a = blipbloup()` can?
201 : :
202 : : // how do we insert ribs here, and only pop them when we exit the current
203 : : // function?
204 : : // keep a list of ribs to pop when a scope exits? so only for blocks?
205 : : // how do we pop ribs that need to be popped not in order?
206 : : // I think it's not important if we have shadowing, correct?
207 : :
208 : : // if we have shadowing, it should work! we'll see
209 : :
210 : : // ctx.insert(Identifier name, NodeId id, Namespace ns)
211 : : // ctx.scoped (Rib::Kind::Normal /* FIXME: Is that valid? */,
212 : : // Namespace::Labels,
213 : : // let.get_node_id (), [] () {});
214 : 1418 : }
215 : :
216 : : void
217 : 2583 : Late::visit (AST::IdentifierPattern &identifier)
218 : : {
219 : : // do we insert in labels or in values
220 : : // but values does not allow shadowing... since functions cannot shadow
221 : : // do we insert functions in labels as well?
222 : :
223 : 2583 : if (ctx.bindings.peek ().is_and_bound (identifier.get_ident ()))
224 : : {
225 : 8 : if (ctx.bindings.peek ().get_source () == BindingSource::Param)
226 : 5 : rust_error_at (
227 : : identifier.get_locus (), ErrorCode::E0415,
228 : : "identifier %qs is bound more than once in the same parameter list",
229 : 10 : identifier.as_string ().c_str ());
230 : : else
231 : 3 : rust_error_at (
232 : : identifier.get_locus (), ErrorCode::E0416,
233 : : "identifier %qs is bound more than once in the same pattern",
234 : 6 : identifier.as_string ().c_str ());
235 : 8 : return;
236 : : }
237 : :
238 : 2575 : ctx.bindings.peek ().insert_ident (identifier.get_ident ());
239 : :
240 : 2575 : if (ctx.bindings.peek ().is_or_bound (identifier.get_ident ()))
241 : : {
242 : : // FIXME: map usage instead
243 : 18 : std::ignore = ctx.values.insert_shadowable (identifier.get_ident (),
244 : 18 : identifier.get_node_id ());
245 : : }
246 : : else
247 : : {
248 : : // We do want to ignore duplicated data because some situations rely on
249 : : // it.
250 : 5132 : std::ignore = ctx.values.insert_shadowable (identifier.get_ident (),
251 : 5132 : identifier.get_node_id ());
252 : : }
253 : : }
254 : :
255 : : void
256 : 11 : Late::visit (AST::AltPattern &pattern)
257 : : {
258 : 11 : ctx.bindings.peek ().push (Binding::Kind::Or);
259 : 36 : for (auto &alt : pattern.get_alts ())
260 : : {
261 : 25 : ctx.bindings.peek ().push (Binding::Kind::Product);
262 : 25 : visit (alt);
263 : 25 : ctx.bindings.peek ().merge ();
264 : : }
265 : 11 : ctx.bindings.peek ().merge ();
266 : 11 : }
267 : :
268 : : void
269 : 2534 : Late::visit_function_params (AST::Function &function)
270 : : {
271 : 2534 : ctx.bindings.enter (BindingSource::Param);
272 : :
273 : 4539 : for (auto ¶m : function.get_function_params ())
274 : 2005 : visit (param);
275 : :
276 : 2534 : ctx.bindings.exit ();
277 : 2534 : }
278 : :
279 : : void
280 : 16 : Late::visit (AST::StructPatternFieldIdent &field)
281 : : {
282 : : // We do want to ignore duplicated data because some situations rely on it.
283 : 32 : std::ignore = ctx.values.insert_shadowable (field.get_identifier (),
284 : 16 : field.get_node_id ());
285 : 16 : }
286 : :
287 : : void
288 : 767 : Late::visit (AST::SelfParam ¶m)
289 : : {
290 : : // handle similar to AST::IdentifierPattern
291 : :
292 : 767 : DefaultResolver::visit (param);
293 : : // FIXME: this location should be a bit off
294 : : // ex: would point to the begining of "mut self" instead of the "self"
295 : 2301 : std::ignore = ctx.values.insert (Identifier ("self", param.get_locus ()),
296 : 767 : param.get_node_id ());
297 : 767 : }
298 : :
299 : : void
300 : 29 : Late::visit (AST::BreakExpr &expr)
301 : : {
302 : 29 : if (expr.has_label ())
303 : 13 : resolve_label (expr.get_label_unchecked ().get_lifetime ());
304 : :
305 : 29 : if (expr.has_break_expr ())
306 : : {
307 : 8 : auto &break_expr = expr.get_break_expr ();
308 : 8 : if (break_expr.get_expr_kind () == AST::Expr::Kind::Identifier)
309 : : {
310 : : /* This is a break with an expression, and the expression is
311 : : just a single identifier. See if the identifier is either
312 : : "rust" or "gcc", in which case we have "break rust" or "break
313 : : gcc", and so may need to emit our funny error. We cannot yet
314 : : emit the error here though, because the identifier may still
315 : : be in scope, and ICE'ing on valid programs would not be very
316 : : funny. */
317 : 5 : std::string ident
318 : 5 : = static_cast<AST::IdentifierExpr &> (expr.get_break_expr ())
319 : 5 : .as_string ();
320 : 5 : if (ident == "rust" || ident == "gcc")
321 : 2 : funny_error = true;
322 : 5 : }
323 : : }
324 : :
325 : 29 : DefaultResolver::visit (expr);
326 : :
327 : 28 : funny_error = false;
328 : 28 : }
329 : :
330 : : void
331 : 27 : Late::visit (AST::LoopLabel &label)
332 : : {
333 : 27 : auto &lifetime = label.get_lifetime ();
334 : 54 : ctx.labels.insert (Identifier (lifetime.as_string (), lifetime.get_locus ()),
335 : : lifetime.get_node_id ());
336 : 27 : }
337 : :
338 : : void
339 : 14 : Late::resolve_label (AST::Lifetime &lifetime)
340 : : {
341 : 28 : if (auto resolved = ctx.labels.get (lifetime.as_string ()))
342 : : {
343 : 6 : if (resolved->get_node_id () != lifetime.get_node_id ())
344 : 6 : ctx.map_usage (Usage (lifetime.get_node_id ()),
345 : 6 : Definition (resolved->get_node_id ()));
346 : : }
347 : : else
348 : 8 : rust_error_at (lifetime.get_locus (), ErrorCode::E0426,
349 : : "use of undeclared label %qs",
350 : 16 : lifetime.as_string ().c_str ());
351 : 14 : }
352 : :
353 : : void
354 : 4 : Late::visit (AST::ContinueExpr &expr)
355 : : {
356 : 4 : if (expr.has_label ())
357 : 1 : resolve_label (expr.get_label_unchecked ());
358 : :
359 : 4 : DefaultResolver::visit (expr);
360 : 4 : }
361 : :
362 : : void
363 : 2171 : Late::visit (AST::IdentifierExpr &expr)
364 : : {
365 : : // TODO: same thing as visit(PathInExpression) here?
366 : :
367 : 2171 : tl::optional<Rib::Definition> resolved = tl::nullopt;
368 : 2171 : if (auto value = ctx.values.get (expr.get_ident ()))
369 : : {
370 : 2154 : resolved = value;
371 : : }
372 : 17 : else if (auto type = ctx.types.get (expr.get_ident ()))
373 : : {
374 : 7 : resolved = type;
375 : : }
376 : 10 : else if (funny_error)
377 : : {
378 : 1 : diagnostic_text_finalizer (global_dc) = Resolver::funny_ice_text_finalizer;
379 : 1 : emit_diagnostic (DK_ICE_NOBT, expr.get_locus (), -1,
380 : : "are you trying to break %s? how dare you?",
381 : 1 : expr.as_string ().c_str ());
382 : : }
383 : : else
384 : : {
385 : 9 : if (auto type = ctx.types.get_lang_prelude (expr.get_ident ()))
386 : : {
387 : 3 : resolved = type;
388 : : }
389 : : else
390 : : {
391 : 6 : rust_error_at (expr.get_locus (), ErrorCode::E0425,
392 : : "cannot find value %qs in this scope",
393 : 6 : expr.get_ident ().as_string ().c_str ());
394 : 6 : return;
395 : 9 : }
396 : 16 : }
397 : :
398 : 2164 : if (resolved->is_ambiguous ())
399 : : {
400 : 0 : rust_error_at (expr.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
401 : 0 : expr.as_string ().c_str ());
402 : 0 : return;
403 : : }
404 : :
405 : 2164 : ctx.map_usage (Usage (expr.get_node_id ()),
406 : 2164 : Definition (resolved->get_node_id ()));
407 : :
408 : : // For empty types, do we perform a lookup in ctx.types or should the
409 : : // toplevel instead insert a name in ctx.values? (like it currently does)
410 : 2170 : }
411 : :
412 : : void
413 : 19 : Late::visit (AST::StructExprFieldIdentifier &expr)
414 : : {
415 : 19 : tl::optional<Rib::Definition> resolved = tl::nullopt;
416 : :
417 : 19 : if (auto value = ctx.values.get (expr.get_field_name ()))
418 : : {
419 : 19 : resolved = value;
420 : : }
421 : : // seems like we don't need a type namespace lookup
422 : : else
423 : : {
424 : 0 : rust_error_at (expr.get_locus (), "could not resolve struct field: %qs",
425 : 0 : expr.get_field_name ().as_string ().c_str ());
426 : 0 : return;
427 : 0 : }
428 : :
429 : 19 : if (resolved->is_ambiguous ())
430 : : {
431 : 0 : rust_error_at (expr.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
432 : 0 : expr.as_string ().c_str ());
433 : 0 : return;
434 : : }
435 : :
436 : 19 : ctx.map_usage (Usage (expr.get_node_id ()),
437 : 19 : Definition (resolved->get_node_id ()));
438 : 19 : }
439 : :
440 : : void
441 : 2069 : Late::visit (AST::PathInExpression &expr)
442 : : {
443 : : // TODO: How do we have a nice error with `can't capture dynamic environment
444 : : // in a function item` error here?
445 : : // do we emit it in `get<Namespace::Labels>`?
446 : :
447 : 2069 : DefaultResolver::visit (expr);
448 : :
449 : 2069 : if (expr.is_lang_item ())
450 : : {
451 : 18 : ctx.map_usage (Usage (expr.get_node_id ()),
452 : 18 : Definition (Analysis::Mappings::get ().get_lang_item_node (
453 : 18 : expr.get_lang_item ())));
454 : 311 : return;
455 : : }
456 : :
457 : 2051 : auto resolved = ctx.resolve_path (expr, Namespace::Values, Namespace::Types);
458 : :
459 : 2051 : if (!resolved)
460 : : {
461 : 291 : if (!ctx.lookup (expr.get_segments ().front ().get_node_id ()))
462 : 4 : rust_error_at (expr.get_locus (), ErrorCode::E0433,
463 : : "Cannot find path %qs in this scope",
464 : 4 : expr.as_simple_path ().as_string ().c_str ());
465 : 291 : return;
466 : : }
467 : :
468 : 1760 : if (resolved->is_ambiguous ())
469 : : {
470 : 2 : rust_error_at (expr.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
471 : 2 : expr.as_string ().c_str ());
472 : 2 : return;
473 : : }
474 : :
475 : 1758 : ctx.map_usage (Usage (expr.get_node_id ()),
476 : 1758 : Definition (resolved->get_node_id ()));
477 : 2051 : }
478 : :
479 : : void
480 : 6642 : Late::visit (AST::TypePath &type)
481 : : {
482 : : // should we add type path resolution in `ForeverStack` directly? Since it's
483 : : // quite more complicated.
484 : : // maybe we can overload `resolve_path<Namespace::Types>` to only do
485 : : // typepath-like path resolution? that sounds good
486 : :
487 : 6642 : DefaultResolver::visit (type);
488 : :
489 : : // this *should* mostly work
490 : : // TODO: make sure typepath-like path resolution (?) is working
491 : 6642 : auto resolved = ctx.resolve_path (type, Namespace::Types);
492 : :
493 : 6642 : if (!resolved.has_value ())
494 : : {
495 : 134 : if (!ctx.lookup (type.get_segments ().front ()->get_node_id ()))
496 : 19 : rust_error_at (type.get_locus (), "could not resolve type path %qs",
497 : 38 : type.as_string ().c_str ());
498 : 134 : return;
499 : : }
500 : :
501 : 6508 : if (resolved->is_ambiguous ())
502 : : {
503 : 0 : rust_error_at (type.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
504 : 0 : type.as_string ().c_str ());
505 : 0 : return;
506 : : }
507 : :
508 : 6508 : if (ctx.types.forward_declared (resolved->get_node_id (),
509 : : type.get_node_id ()))
510 : : {
511 : 2 : rust_error_at (type.get_locus (), ErrorCode::E0128,
512 : : "type parameters with a default cannot use forward "
513 : : "declared identifiers");
514 : : }
515 : :
516 : 6508 : ctx.map_usage (Usage (type.get_node_id ()),
517 : 6508 : Definition (resolved->get_node_id ()));
518 : 6640 : }
519 : :
520 : : void
521 : 569 : Late::visit (AST::Trait &trait)
522 : : {
523 : : // kind of weird how this is done
524 : : // names are resolved to the node id of trait.get_implicit_self ()
525 : : // which is then resolved to the node id of trait
526 : : // we set up the latter mapping here
527 : 1138 : ctx.map_usage (Usage (trait.get_implicit_self ().get_node_id ()),
528 : 569 : Definition (trait.get_node_id ()));
529 : :
530 : 569 : DefaultResolver::visit (trait);
531 : 569 : }
532 : :
533 : : void
534 : 322 : Late::visit (AST::StructStruct &s)
535 : : {
536 : 322 : auto s_vis = [this, &s] () { AST::DefaultASTVisitor::visit (s); };
537 : 322 : ctx.scoped (Rib::Kind::Item, s.get_node_id (), s_vis);
538 : 321 : }
539 : :
540 : : void
541 : 10 : Late::visit (AST::StructExprStruct &s)
542 : : {
543 : 10 : visit_outer_attrs (s);
544 : 10 : visit_inner_attrs (s);
545 : 10 : DefaultResolver::visit (s.get_struct_name ());
546 : :
547 : 10 : auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
548 : :
549 : 10 : ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
550 : 10 : Definition (resolved->get_node_id ()));
551 : 10 : }
552 : :
553 : : void
554 : 0 : Late::visit (AST::StructExprStructBase &s)
555 : : {
556 : 0 : visit_outer_attrs (s);
557 : 0 : visit_inner_attrs (s);
558 : 0 : DefaultResolver::visit (s.get_struct_name ());
559 : 0 : visit (s.get_struct_base ());
560 : :
561 : 0 : auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
562 : :
563 : 0 : ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
564 : 0 : Definition (resolved->get_node_id ()));
565 : 0 : }
566 : :
567 : : void
568 : 161 : Late::visit (AST::StructExprStructFields &s)
569 : : {
570 : 161 : visit_outer_attrs (s);
571 : 161 : visit_inner_attrs (s);
572 : 161 : DefaultResolver::visit (s.get_struct_name ());
573 : 161 : if (s.has_struct_base ())
574 : 9 : visit (s.get_struct_base ());
575 : 449 : for (auto &field : s.get_fields ())
576 : 288 : visit (field);
577 : :
578 : 161 : auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
579 : :
580 : 161 : ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
581 : 161 : Definition (resolved->get_node_id ()));
582 : 161 : }
583 : :
584 : : // needed because Late::visit (AST::GenericArg &) is non-virtual
585 : : void
586 : 606 : Late::visit (AST::GenericArgs &args)
587 : : {
588 : 630 : for (auto &lifetime : args.get_lifetime_args ())
589 : 24 : visit (lifetime);
590 : :
591 : 1253 : for (auto &generic : args.get_generic_args ())
592 : 647 : visit (generic);
593 : :
594 : 620 : for (auto &binding : args.get_binding_args ())
595 : 14 : visit (binding);
596 : 606 : }
597 : :
598 : : void
599 : 647 : Late::visit (AST::GenericArg &arg)
600 : : {
601 : 647 : if (arg.get_kind () == AST::GenericArg::Kind::Either)
602 : : {
603 : : // prefer type parameter to const parameter on ambiguity
604 : 854 : auto type = ctx.types.get (arg.get_path ());
605 : 854 : auto value = ctx.values.get (arg.get_path ());
606 : :
607 : 427 : if (!type.has_value () && value.has_value ())
608 : 9 : arg = arg.disambiguate_to_const ();
609 : : else
610 : 418 : arg = arg.disambiguate_to_type ();
611 : 557 : }
612 : :
613 : 647 : DefaultResolver::visit (arg);
614 : 647 : }
615 : :
616 : : template <class Closure>
617 : : static void
618 : 7 : add_captures (Closure &closure, NameResolutionContext &ctx)
619 : : {
620 : 7 : auto vals = ctx.values.peek ().get_values ();
621 : 7 : for (auto &val : vals)
622 : : {
623 : 0 : ctx.mappings.add_capture (closure.get_node_id (),
624 : : val.second.get_node_id ());
625 : : }
626 : 7 : }
627 : :
628 : : void
629 : 5 : Late::visit (AST::ClosureExprInner &closure)
630 : : {
631 : 5 : add_captures (closure, ctx);
632 : :
633 : 5 : visit_outer_attrs (closure);
634 : :
635 : 5 : ctx.bindings.enter (BindingSource::Param);
636 : :
637 : 9 : for (auto ¶m : closure.get_params ())
638 : 4 : visit (param);
639 : :
640 : 5 : ctx.bindings.exit ();
641 : :
642 : 5 : visit (closure.get_definition_expr ());
643 : 5 : }
644 : :
645 : : void
646 : 2 : Late::visit (AST::ClosureExprInnerTyped &closure)
647 : : {
648 : 2 : add_captures (closure, ctx);
649 : :
650 : 2 : visit_outer_attrs (closure);
651 : :
652 : 2 : ctx.bindings.enter (BindingSource::Param);
653 : :
654 : 4 : for (auto ¶m : closure.get_params ())
655 : 2 : visit (param);
656 : :
657 : 2 : ctx.bindings.exit ();
658 : :
659 : 2 : visit (closure.get_return_type ());
660 : 2 : visit (closure.get_definition_block ());
661 : 2 : }
662 : :
663 : : } // namespace Resolver2_0
664 : : } // namespace Rust
|