Branch data Line data Source code
1 : : // Copyright (C) 2020-2024 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-late-name-resolver-2.0.h"
22 : : #include "rust-default-resolver.h"
23 : : #include "rust-path.h"
24 : : #include "rust-tyty.h"
25 : : #include "rust-hir-type-check.h"
26 : :
27 : : namespace Rust {
28 : : namespace Resolver2_0 {
29 : :
30 : 0 : Late::Late (NameResolutionContext &ctx) : DefaultResolver (ctx) {}
31 : :
32 : : void
33 : 0 : Late::setup_builtin_types ()
34 : : {
35 : 0 : auto next_id = [this] () { return ctx.mappings.get_next_hir_id (); };
36 : :
37 : 0 : static const std::pair<std::string, TyTy::BaseType *> builtins[] = {
38 : 0 : {"u8", new TyTy::UintType (next_id (), TyTy::UintType::U8)},
39 : 0 : {"u16", new TyTy::UintType (next_id (), TyTy::UintType::U16)},
40 : 0 : {"u32", new TyTy::UintType (next_id (), TyTy::UintType::U32)},
41 : 0 : {"u64", new TyTy::UintType (next_id (), TyTy::UintType::U64)},
42 : 0 : {"u128", new TyTy::UintType (next_id (), TyTy::UintType::U128)},
43 : 0 : {"i8", new TyTy::IntType (next_id (), TyTy::IntType::I8)},
44 : 0 : {"i16", new TyTy::IntType (next_id (), TyTy::IntType::I16)},
45 : 0 : {"i32", new TyTy::IntType (next_id (), TyTy::IntType::I32)},
46 : 0 : {"i64", new TyTy::IntType (next_id (), TyTy::IntType::I64)},
47 : 0 : {"i128", new TyTy::IntType (next_id (), TyTy::IntType::I128)},
48 : 0 : {"f32", new TyTy::FloatType (next_id (), TyTy::FloatType::F32)},
49 : 0 : {"f64", new TyTy::FloatType (next_id (), TyTy::FloatType::F64)},
50 : 0 : {"usize", new TyTy::USizeType (next_id ())},
51 : 0 : {"isize", new TyTy::ISizeType (next_id ())},
52 : : // missing char, str, never, ()
53 : : // does name resolution play a part for this? or is it all at typechecking?
54 : : // yeah it seems to be name resolution as well, which makes sense
55 : 0 : };
56 : :
57 : 0 : for (const auto &builtin : builtins)
58 : : {
59 : : // we should be able to use `insert_at_root` or `insert` here, since we're
60 : : // at the root :) hopefully!
61 : 0 : auto ok
62 : 0 : = ctx.types.insert (builtin.first, builtin.second->get_ref ()
63 : 0 : /* FIXME: Invalid! This returns an *HirId* */);
64 : :
65 : 0 : rust_assert (ok);
66 : 0 : }
67 : 0 : }
68 : :
69 : : void
70 : 0 : Late::go (AST::Crate &crate)
71 : : {
72 : 0 : setup_builtin_types ();
73 : :
74 : 0 : for (auto &item : crate.items)
75 : 0 : item->accept_vis (*this);
76 : 0 : }
77 : :
78 : : void
79 : 0 : Late::new_label (Identifier name, NodeId id)
80 : : {
81 : : // labels can always shadow, so `insert` should never fail. if it does, we're
82 : : // in big trouble!
83 : 0 : auto ok = ctx.labels.insert (name, id);
84 : :
85 : 0 : rust_assert (ok);
86 : 0 : }
87 : :
88 : : void
89 : 0 : Late::visit (AST::LetStmt &let)
90 : : {
91 : : // so we don't need that method
92 : 0 : DefaultResolver::visit (let);
93 : :
94 : : // how do we deal with the fact that `let a = blipbloup` should look for a
95 : : // label and cannot go through function ribs, but `let a = blipbloup()` can?
96 : :
97 : : // how do we insert ribs here, and only pop them when we exit the current
98 : : // function?
99 : : // keep a list of ribs to pop when a scope exits? so only for blocks?
100 : : // how do we pop ribs that need to be popped not in order?
101 : : // I think it's not important if we have shadowing, correct?
102 : :
103 : : // if we have shadowing, it should work! we'll see
104 : :
105 : : // ctx.insert(Identifier name, NodeId id, Namespace ns)
106 : : // ctx.scoped (Rib::Kind::Normal /* FIXME: Is that valid? */,
107 : : // Namespace::Labels,
108 : : // let.get_node_id (), [] () {});
109 : 0 : }
110 : :
111 : : void
112 : 0 : Late::visit (AST::IdentifierPattern &identifier)
113 : : {
114 : : // do we insert in labels or in values
115 : : // but values does not allow shadowing... since functions cannot shadow
116 : : // do we insert functions in labels as well?
117 : 0 : new_label (identifier.get_ident (), identifier.get_node_id ());
118 : 0 : }
119 : :
120 : : void
121 : 0 : Late::visit (AST::IdentifierExpr &expr)
122 : : {
123 : : // TODO: same thing as visit(PathInExpression) here?
124 : :
125 : 0 : tl::optional<NodeId> resolved = tl::nullopt;
126 : 0 : auto label = ctx.labels.get (expr.get_ident ());
127 : 0 : auto value = ctx.values.get (expr.get_ident ());
128 : :
129 : 0 : if (label)
130 : 0 : resolved = label;
131 : 0 : else if (value)
132 : 0 : resolved = value;
133 : : // TODO: else emit error?
134 : :
135 : 0 : ctx.map_usage (expr.get_node_id (), *resolved);
136 : :
137 : : // in the old resolver, resolutions are kept in the resolver, not the mappings
138 : : // :/ how do we deal with that?
139 : : // ctx.mappings.insert_resolved_name(expr, resolved);
140 : :
141 : : // For empty types, do we perform a lookup in ctx.types or should the
142 : : // toplevel instead insert a name in ctx.values? (like it currently does)
143 : 0 : }
144 : :
145 : : void
146 : 0 : Late::visit (AST::PathInExpression &expr)
147 : : {
148 : : // TODO: How do we have a nice error with `can't capture dynamic environment
149 : : // in a function item` error here?
150 : : // do we emit it in `get<Namespace::Labels>`?
151 : :
152 : 0 : auto label = ctx.labels.resolve_path (expr.get_segments ());
153 : 0 : auto value = ctx.values.resolve_path (expr.get_segments ());
154 : 0 : }
155 : :
156 : : void
157 : 0 : Late::visit (AST::TypePath &type)
158 : : {
159 : : // should we add type path resolution in `ForeverStack` directly? Since it's
160 : : // quite more complicated.
161 : : // maybe we can overload `resolve_path<Namespace::Types>` to only do
162 : : // typepath-like path resolution? that sounds good
163 : :
164 : 0 : auto resolved = ctx.types.get (type.get_segments ().back ()->as_string ());
165 : :
166 : 0 : ctx.map_usage (type.get_node_id (), *resolved);
167 : 0 : }
168 : :
169 : : } // namespace Resolver2_0
170 : : } // namespace Rust
|