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 : 912 : Late::Late (NameResolutionContext &ctx) : DefaultResolver (ctx) {}
37 : :
38 : : static NodeId
39 : 17328 : next_node_id ()
40 : : {
41 : 17328 : return Analysis::Mappings::get ().get_next_node_id ();
42 : : };
43 : :
44 : : static HirId
45 : 16416 : next_hir_id ()
46 : : {
47 : 16416 : return Analysis::Mappings::get ().get_next_hir_id ();
48 : : };
49 : :
50 : : void
51 : 912 : Late::setup_builtin_types ()
52 : : {
53 : : // access the global type context to setup the TyTys
54 : 912 : auto &ty_ctx = *Resolver::TypeCheckContext::get ();
55 : :
56 : : // Late builtin type struct helper
57 : 912 : struct LType
58 : : {
59 : : std::string name;
60 : : NodeId node_id;
61 : : NodeId hir_id;
62 : : TyTy::BaseType *type;
63 : :
64 : 16416 : explicit LType (std::string name, TyTy::BaseType *type)
65 : 16416 : : name (name), node_id (next_node_id ()), hir_id (type->get_ref ()),
66 : 16416 : type (type)
67 : 16416 : {}
68 : : };
69 : :
70 : 912 : static const LType builtins[] = {
71 : 1824 : {LType ("bool", new TyTy::BoolType (next_hir_id ()))},
72 : 1824 : {LType ("u8", new TyTy::UintType (next_hir_id (), TyTy::UintType::U8))},
73 : 1824 : {LType ("u16", new TyTy::UintType (next_hir_id (), TyTy::UintType::U16))},
74 : 1824 : {LType ("u32", new TyTy::UintType (next_hir_id (), TyTy::UintType::U32))},
75 : 1824 : {LType ("u64", new TyTy::UintType (next_hir_id (), TyTy::UintType::U64))},
76 : 1824 : {LType ("u128", new TyTy::UintType (next_hir_id (), TyTy::UintType::U128))},
77 : 1824 : {LType ("i8", new TyTy::IntType (next_hir_id (), TyTy::IntType::I8))},
78 : 1824 : {LType ("i16", new TyTy::IntType (next_hir_id (), TyTy::IntType::I16))},
79 : 1824 : {LType ("i32", new TyTy::IntType (next_hir_id (), TyTy::IntType::I32))},
80 : 1824 : {LType ("i64", new TyTy::IntType (next_hir_id (), TyTy::IntType::I64))},
81 : 1824 : {LType ("i128", new TyTy::IntType (next_hir_id (), TyTy::IntType::I128))},
82 : 1824 : {LType ("f32", new TyTy::FloatType (next_hir_id (), TyTy::FloatType::F32))},
83 : 1824 : {LType ("f64", new TyTy::FloatType (next_hir_id (), TyTy::FloatType::F64))},
84 : 1824 : {LType ("usize", new TyTy::USizeType (next_hir_id ()))},
85 : 1824 : {LType ("isize", new TyTy::ISizeType (next_hir_id ()))},
86 : 1824 : {LType ("char", new TyTy::CharType (next_hir_id ()))},
87 : 1824 : {LType ("str", new TyTy::StrType (next_hir_id ()))},
88 : 1824 : {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 : 18240 : };
93 : :
94 : : // There's a special Rib for putting prelude items, since prelude items need
95 : : // to satisfy certain special rules.
96 : 912 : ctx.scoped (Rib::Kind::Prelude, 0, [this, &ty_ctx] (void) -> void {
97 : 17328 : for (const auto &builtin : builtins)
98 : : {
99 : 16416 : auto ok = ctx.types.insert (builtin.name, builtin.node_id);
100 : 16416 : rust_assert (ok);
101 : :
102 : 16416 : ctx.mappings.insert_node_to_hir (builtin.node_id, builtin.hir_id);
103 : 16416 : ty_ctx.insert_builtin (builtin.hir_id, builtin.node_id, builtin.type);
104 : 16416 : }
105 : 912 : });
106 : :
107 : : // ...here!
108 : 912 : auto *unit_type = TyTy::TupleType::get_unit_type ();
109 : 912 : ty_ctx.insert_builtin (unit_type->get_ref (), next_node_id (), unit_type);
110 : 912 : }
111 : :
112 : : void
113 : 912 : Late::go (AST::Crate &crate)
114 : : {
115 : 912 : setup_builtin_types ();
116 : :
117 : 3876 : for (auto &item : crate.items)
118 : 2968 : item->accept_vis (*this);
119 : 908 : }
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 : 1360 : Late::visit (AST::LetStmt &let)
133 : : {
134 : 1360 : DefaultASTVisitor::visit_outer_attrs (let);
135 : 1360 : if (let.has_type ())
136 : 351 : visit (let.get_type ());
137 : : // visit expression before pattern
138 : : // this makes variable shadowing work properly
139 : 1360 : if (let.has_init_expr ())
140 : 1192 : visit (let.get_init_expr ());
141 : 1360 : visit (let.get_pattern ());
142 : :
143 : 1360 : if (let.has_else_expr ())
144 : 0 : visit (let.get_init_expr ());
145 : :
146 : : // how do we deal with the fact that `let a = blipbloup` should look for a
147 : : // label and cannot go through function ribs, but `let a = blipbloup()` can?
148 : :
149 : : // how do we insert ribs here, and only pop them when we exit the current
150 : : // function?
151 : : // keep a list of ribs to pop when a scope exits? so only for blocks?
152 : : // how do we pop ribs that need to be popped not in order?
153 : : // I think it's not important if we have shadowing, correct?
154 : :
155 : : // if we have shadowing, it should work! we'll see
156 : :
157 : : // ctx.insert(Identifier name, NodeId id, Namespace ns)
158 : : // ctx.scoped (Rib::Kind::Normal /* FIXME: Is that valid? */,
159 : : // Namespace::Labels,
160 : : // let.get_node_id (), [] () {});
161 : 1360 : }
162 : :
163 : : void
164 : 2497 : Late::visit (AST::IdentifierPattern &identifier)
165 : : {
166 : : // do we insert in labels or in values
167 : : // but values does not allow shadowing... since functions cannot shadow
168 : : // do we insert functions in labels as well?
169 : :
170 : : // We do want to ignore duplicated data because some situations rely on it.
171 : 4994 : std::ignore = ctx.values.insert_shadowable (identifier.get_ident (),
172 : 4994 : identifier.get_node_id ());
173 : 2497 : }
174 : :
175 : : void
176 : 742 : Late::visit (AST::SelfParam ¶m)
177 : : {
178 : : // handle similar to AST::IdentifierPattern
179 : :
180 : 742 : DefaultResolver::visit (param);
181 : : // FIXME: this location should be a bit off
182 : : // ex: would point to the begining of "mut self" instead of the "self"
183 : 1484 : std::ignore = ctx.values.insert (Identifier ("self", param.get_locus ()),
184 : 742 : param.get_node_id ());
185 : 742 : }
186 : :
187 : : void
188 : 28 : Late::visit (AST::BreakExpr &expr)
189 : : {
190 : 28 : if (expr.has_label ())
191 : 13 : resolve_label (expr.get_label_unchecked ().get_lifetime ());
192 : :
193 : 28 : if (expr.has_break_expr ())
194 : : {
195 : 8 : auto &break_expr = expr.get_break_expr ();
196 : 8 : if (break_expr.get_expr_kind () == AST::Expr::Kind::Identifier)
197 : : {
198 : : /* This is a break with an expression, and the expression is
199 : : just a single identifier. See if the identifier is either
200 : : "rust" or "gcc", in which case we have "break rust" or "break
201 : : gcc", and so may need to emit our funny error. We cannot yet
202 : : emit the error here though, because the identifier may still
203 : : be in scope, and ICE'ing on valid programs would not be very
204 : : funny. */
205 : 5 : std::string ident
206 : 5 : = static_cast<AST::IdentifierExpr &> (expr.get_break_expr ())
207 : 5 : .as_string ();
208 : 5 : if (ident == "rust" || ident == "gcc")
209 : 2 : funny_error = true;
210 : 5 : }
211 : : }
212 : :
213 : 28 : DefaultResolver::visit (expr);
214 : :
215 : 27 : funny_error = false;
216 : 27 : }
217 : :
218 : : void
219 : 27 : Late::visit (AST::LoopLabel &label)
220 : : {
221 : 27 : auto &lifetime = label.get_lifetime ();
222 : 27 : ctx.labels.insert (Identifier (lifetime.as_string (), lifetime.get_locus ()),
223 : : lifetime.get_node_id ());
224 : 27 : }
225 : :
226 : : void
227 : 14 : Late::resolve_label (AST::Lifetime &lifetime)
228 : : {
229 : 14 : if (auto resolved = ctx.labels.get (lifetime.as_string ()))
230 : : {
231 : 6 : if (resolved->get_node_id () != lifetime.get_node_id ())
232 : 6 : ctx.map_usage (Usage (lifetime.get_node_id ()),
233 : 6 : Definition (resolved->get_node_id ()));
234 : : }
235 : : else
236 : 8 : rust_error_at (lifetime.get_locus (), ErrorCode::E0426,
237 : : "use of undeclared label %qs",
238 : 16 : lifetime.as_string ().c_str ());
239 : 14 : }
240 : :
241 : : void
242 : 4 : Late::visit (AST::ContinueExpr &expr)
243 : : {
244 : 4 : if (expr.has_label ())
245 : 1 : resolve_label (expr.get_label_unchecked ());
246 : :
247 : 4 : DefaultResolver::visit (expr);
248 : 4 : }
249 : :
250 : : void
251 : 2080 : Late::visit (AST::IdentifierExpr &expr)
252 : : {
253 : : // TODO: same thing as visit(PathInExpression) here?
254 : :
255 : 2080 : tl::optional<Rib::Definition> resolved = tl::nullopt;
256 : 2080 : if (auto value = ctx.values.get (expr.get_ident ()))
257 : : {
258 : 2062 : resolved = value;
259 : : }
260 : 18 : else if (auto type = ctx.types.get (expr.get_ident ()))
261 : : {
262 : 7 : resolved = type;
263 : : }
264 : 11 : else if (funny_error)
265 : : {
266 : 1 : diagnostic_text_finalizer (global_dc) = Resolver::funny_ice_text_finalizer;
267 : 1 : emit_diagnostic (DK_ICE_NOBT, expr.get_locus (), -1,
268 : : "are you trying to break %s? how dare you?",
269 : 1 : expr.as_string ().c_str ());
270 : : }
271 : : else
272 : : {
273 : 10 : if (auto type = ctx.types.get_lang_prelude (expr.get_ident ()))
274 : : {
275 : 3 : resolved = type;
276 : : }
277 : : else
278 : : {
279 : 7 : rust_error_at (expr.get_locus (), ErrorCode::E0425,
280 : : "cannot find value %qs in this scope",
281 : 7 : expr.get_ident ().as_string ().c_str ());
282 : 7 : return;
283 : 10 : }
284 : 17 : }
285 : :
286 : 2072 : if (resolved->is_ambiguous ())
287 : : {
288 : 0 : rust_error_at (expr.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
289 : 0 : expr.as_string ().c_str ());
290 : 0 : return;
291 : : }
292 : :
293 : 2072 : ctx.map_usage (Usage (expr.get_node_id ()),
294 : 2072 : Definition (resolved->get_node_id ()));
295 : :
296 : : // For empty types, do we perform a lookup in ctx.types or should the
297 : : // toplevel instead insert a name in ctx.values? (like it currently does)
298 : 2079 : }
299 : :
300 : : void
301 : 19 : Late::visit (AST::StructExprFieldIdentifier &expr)
302 : : {
303 : 19 : tl::optional<Rib::Definition> resolved = tl::nullopt;
304 : :
305 : 19 : if (auto value = ctx.values.get (expr.get_field_name ()))
306 : : {
307 : 19 : resolved = value;
308 : : }
309 : : // seems like we don't need a type namespace lookup
310 : : else
311 : : {
312 : 0 : rust_error_at (expr.get_locus (), "could not resolve struct field: %qs",
313 : 0 : expr.get_field_name ().as_string ().c_str ());
314 : 0 : return;
315 : 0 : }
316 : :
317 : 19 : if (resolved->is_ambiguous ())
318 : : {
319 : 0 : rust_error_at (expr.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
320 : 0 : expr.as_string ().c_str ());
321 : 0 : return;
322 : : }
323 : :
324 : 19 : ctx.map_usage (Usage (expr.get_node_id ()),
325 : 19 : Definition (resolved->get_node_id ()));
326 : 19 : }
327 : :
328 : : void
329 : 2008 : Late::visit (AST::PathInExpression &expr)
330 : : {
331 : : // TODO: How do we have a nice error with `can't capture dynamic environment
332 : : // in a function item` error here?
333 : : // do we emit it in `get<Namespace::Labels>`?
334 : :
335 : 2008 : DefaultResolver::visit (expr);
336 : :
337 : 2008 : if (expr.is_lang_item ())
338 : : {
339 : 18 : ctx.map_usage (Usage (expr.get_node_id ()),
340 : 18 : Definition (Analysis::Mappings::get ().get_lang_item_node (
341 : 18 : expr.get_lang_item ())));
342 : 292 : return;
343 : : }
344 : :
345 : 1990 : auto resolved = ctx.resolve_path (expr, Namespace::Values, Namespace::Types);
346 : :
347 : 1990 : if (!resolved)
348 : : {
349 : 273 : if (!ctx.lookup (expr.get_segments ().front ().get_node_id ()))
350 : 4 : rust_error_at (expr.get_locus (),
351 : : "could not resolve path expression: %qs",
352 : 4 : expr.as_simple_path ().as_string ().c_str ());
353 : 273 : return;
354 : : }
355 : :
356 : 1717 : if (resolved->is_ambiguous ())
357 : : {
358 : 1 : rust_error_at (expr.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
359 : 1 : expr.as_string ().c_str ());
360 : 1 : return;
361 : : }
362 : :
363 : 1716 : ctx.map_usage (Usage (expr.get_node_id ()),
364 : 1716 : Definition (resolved->get_node_id ()));
365 : 1990 : }
366 : :
367 : : void
368 : 6284 : Late::visit (AST::TypePath &type)
369 : : {
370 : : // should we add type path resolution in `ForeverStack` directly? Since it's
371 : : // quite more complicated.
372 : : // maybe we can overload `resolve_path<Namespace::Types>` to only do
373 : : // typepath-like path resolution? that sounds good
374 : :
375 : 6284 : DefaultResolver::visit (type);
376 : :
377 : : // this *should* mostly work
378 : : // TODO: make sure typepath-like path resolution (?) is working
379 : 6284 : auto resolved = ctx.resolve_path (type, Namespace::Types);
380 : :
381 : 6284 : if (!resolved.has_value ())
382 : : {
383 : 112 : if (!ctx.lookup (type.get_segments ().front ()->get_node_id ()))
384 : 7 : rust_error_at (type.get_locus (), "could not resolve type path %qs",
385 : 14 : type.as_string ().c_str ());
386 : 112 : return;
387 : : }
388 : :
389 : 6172 : if (resolved->is_ambiguous ())
390 : : {
391 : 0 : rust_error_at (type.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
392 : 0 : type.as_string ().c_str ());
393 : 0 : return;
394 : : }
395 : :
396 : 6172 : ctx.map_usage (Usage (type.get_node_id ()),
397 : 6172 : Definition (resolved->get_node_id ()));
398 : 6282 : }
399 : :
400 : : void
401 : 504 : Late::visit (AST::Trait &trait)
402 : : {
403 : : // kind of weird how this is done
404 : : // names are resolved to the node id of trait.get_implicit_self ()
405 : : // which is then resolved to the node id of trait
406 : : // we set up the latter mapping here
407 : 1008 : ctx.map_usage (Usage (trait.get_implicit_self ().get_node_id ()),
408 : 504 : Definition (trait.get_node_id ()));
409 : :
410 : 504 : DefaultResolver::visit (trait);
411 : 504 : }
412 : :
413 : : void
414 : 276 : Late::visit (AST::StructStruct &s)
415 : : {
416 : 276 : auto s_vis = [this, &s] () { AST::DefaultASTVisitor::visit (s); };
417 : 276 : ctx.scoped (Rib::Kind::Item, s.get_node_id (), s_vis);
418 : 275 : }
419 : :
420 : : void
421 : 10 : Late::visit (AST::StructExprStruct &s)
422 : : {
423 : 10 : visit_outer_attrs (s);
424 : 10 : visit_inner_attrs (s);
425 : 10 : DefaultResolver::visit (s.get_struct_name ());
426 : :
427 : 10 : auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
428 : :
429 : 10 : ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
430 : 10 : Definition (resolved->get_node_id ()));
431 : 10 : }
432 : :
433 : : void
434 : 0 : Late::visit (AST::StructExprStructBase &s)
435 : : {
436 : 0 : visit_outer_attrs (s);
437 : 0 : visit_inner_attrs (s);
438 : 0 : DefaultResolver::visit (s.get_struct_name ());
439 : 0 : visit (s.get_struct_base ());
440 : :
441 : 0 : auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
442 : :
443 : 0 : ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
444 : 0 : Definition (resolved->get_node_id ()));
445 : 0 : }
446 : :
447 : : void
448 : 142 : Late::visit (AST::StructExprStructFields &s)
449 : : {
450 : 142 : visit_outer_attrs (s);
451 : 142 : visit_inner_attrs (s);
452 : 142 : DefaultResolver::visit (s.get_struct_name ());
453 : 142 : if (s.has_struct_base ())
454 : 9 : visit (s.get_struct_base ());
455 : 408 : for (auto &field : s.get_fields ())
456 : 266 : visit (field);
457 : :
458 : 142 : auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
459 : :
460 : 142 : ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
461 : 142 : Definition (resolved->get_node_id ()));
462 : 141 : }
463 : :
464 : : // needed because Late::visit (AST::GenericArg &) is non-virtual
465 : : void
466 : 557 : Late::visit (AST::GenericArgs &args)
467 : : {
468 : 571 : for (auto &lifetime : args.get_lifetime_args ())
469 : 14 : visit (lifetime);
470 : :
471 : 1151 : for (auto &generic : args.get_generic_args ())
472 : 594 : visit (generic);
473 : :
474 : 569 : for (auto &binding : args.get_binding_args ())
475 : 12 : visit (binding);
476 : 557 : }
477 : :
478 : : void
479 : 594 : Late::visit (AST::GenericArg &arg)
480 : : {
481 : 594 : if (arg.get_kind () == AST::GenericArg::Kind::Either)
482 : : {
483 : : // prefer type parameter to const parameter on ambiguity
484 : 394 : auto type = ctx.types.get (arg.get_path ());
485 : 394 : auto value = ctx.values.get (arg.get_path ());
486 : :
487 : 394 : if (!type.has_value () && value.has_value ())
488 : 2 : arg = arg.disambiguate_to_const ();
489 : : else
490 : 392 : arg = arg.disambiguate_to_type ();
491 : 519 : }
492 : :
493 : 594 : DefaultResolver::visit (arg);
494 : 594 : }
495 : :
496 : : template <class Closure>
497 : : static void
498 : 4 : add_captures (Closure &closure, NameResolutionContext &ctx)
499 : : {
500 : 4 : auto vals = ctx.values.peek ().get_values ();
501 : 4 : for (auto &val : vals)
502 : : {
503 : 0 : ctx.mappings.add_capture (closure.get_node_id (),
504 : : val.second.get_node_id ());
505 : : }
506 : 4 : }
507 : :
508 : : void
509 : 3 : Late::visit (AST::ClosureExprInner &closure)
510 : : {
511 : 3 : add_captures (closure, ctx);
512 : 3 : DefaultResolver::visit (closure);
513 : 3 : }
514 : :
515 : : void
516 : 1 : Late::visit (AST::ClosureExprInnerTyped &closure)
517 : : {
518 : 1 : add_captures (closure, ctx);
519 : 1 : DefaultResolver::visit (closure);
520 : 1 : }
521 : :
522 : : } // namespace Resolver2_0
523 : : } // namespace Rust
|