Line data Source code
1 : // Copyright (C) 2020-2026 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 : #ifndef RUST_UNIFY
20 : #define RUST_UNIFY
21 :
22 : #include "rust-tyty-util.h"
23 : #include "rust-hir-type-check.h"
24 :
25 : namespace Rust {
26 : namespace Resolver {
27 :
28 : class UnifyRules
29 : {
30 : public:
31 : using ADTPair = std::pair<const TyTy::ADTType *, const TyTy::ADTType *>;
32 : using ActiveADTs = std::set<ADTPair>;
33 :
34 : class ActiveADTGuard
35 : {
36 : public:
37 27061 : ActiveADTGuard (ActiveADTs &active, ADTPair pair)
38 27061 : : active (active), pair (pair), inserted (false)
39 : {
40 27061 : bool found = active.find (this->pair) != active.end ();
41 27061 : if (!found)
42 : {
43 27057 : active.insert (this->pair);
44 27057 : inserted = true;
45 : }
46 27061 : }
47 :
48 27061 : ~ActiveADTGuard ()
49 : {
50 27061 : if (inserted)
51 27057 : active.erase (pair);
52 27061 : }
53 :
54 27061 : bool already_active () const { return !inserted; }
55 :
56 : ActiveADTGuard (const ActiveADTGuard &) = delete;
57 : ActiveADTGuard &operator= (const ActiveADTGuard &) = delete;
58 :
59 : private:
60 : ActiveADTs &active;
61 : ADTPair pair;
62 : bool inserted;
63 : };
64 :
65 : struct InferenceSite
66 : {
67 4416 : InferenceSite (HirId pref, HirId ptyref, TyTy::BaseGeneric *param,
68 : TyTy::BaseType *infer)
69 4416 : : pref (pref), ptyref (ptyref), param (param), infer (infer)
70 : {}
71 :
72 : HirId pref;
73 : HirId ptyref;
74 : TyTy::BaseGeneric *param;
75 : TyTy::BaseType *infer;
76 : };
77 : struct CommitSite
78 : {
79 612980 : CommitSite (TyTy::BaseType *lhs, TyTy::BaseType *rhs,
80 : TyTy::BaseType *resolved)
81 612980 : : lhs (lhs), rhs (rhs), resolved (resolved)
82 : {}
83 :
84 : TyTy::BaseType *lhs;
85 : TyTy::BaseType *rhs;
86 : TyTy::BaseType *resolved;
87 : };
88 :
89 : static TyTy::BaseType *
90 : Resolve (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs, location_t locus,
91 : bool commit_flag, bool emit_error, bool check_bounds, bool infer,
92 : std::vector<CommitSite> &commits, std::vector<InferenceSite> &infers,
93 : ActiveADTs *active_adts = nullptr, bool allow_never_coercion = true);
94 :
95 : static void commit (TyTy::BaseType *base, TyTy::BaseType *other,
96 : TyTy::BaseType *resolved);
97 :
98 : protected:
99 : TyTy::BaseType *expect_inference_variable (TyTy::InferType *ltype,
100 : TyTy::BaseType *rtype);
101 : TyTy::BaseType *expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype);
102 : TyTy::BaseType *expect_str (TyTy::StrType *ltype, TyTy::BaseType *rtype);
103 : TyTy::BaseType *expect_reference (TyTy::ReferenceType *ltype,
104 : TyTy::BaseType *rtype);
105 : TyTy::BaseType *expect_pointer (TyTy::PointerType *ltype,
106 : TyTy::BaseType *rtype);
107 : TyTy::BaseType *expect_param (TyTy::ParamType *ltype, TyTy::BaseType *rtype);
108 : TyTy::BaseType *expect_array (TyTy::ArrayType *ltype, TyTy::BaseType *rtype);
109 : TyTy::BaseType *expect_slice (TyTy::SliceType *ltype, TyTy::BaseType *rtype);
110 : TyTy::BaseType *expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype);
111 : TyTy::BaseType *expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype);
112 : TyTy::BaseType *expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype);
113 : TyTy::BaseType *expect_bool (TyTy::BoolType *ltype, TyTy::BaseType *rtype);
114 : TyTy::BaseType *expect_char (TyTy::CharType *ltype, TyTy::BaseType *rtype);
115 : TyTy::BaseType *expect_int (TyTy::IntType *ltype, TyTy::BaseType *rtype);
116 : TyTy::BaseType *expect_uint (TyTy::UintType *ltype, TyTy::BaseType *rtype);
117 : TyTy::BaseType *expect_float (TyTy::FloatType *ltype, TyTy::BaseType *rtype);
118 : TyTy::BaseType *expect_isize (TyTy::ISizeType *ltype, TyTy::BaseType *rtype);
119 : TyTy::BaseType *expect_usize (TyTy::USizeType *ltype, TyTy::BaseType *rtype);
120 : TyTy::BaseType *expect_never (TyTy::NeverType *ltype, TyTy::BaseType *rtype);
121 : TyTy::BaseType *expect_placeholder (TyTy::PlaceholderType *ltype,
122 : TyTy::BaseType *rtype);
123 : TyTy::BaseType *expect_projection (TyTy::ProjectionType *ltype,
124 : TyTy::BaseType *rtype);
125 : TyTy::BaseType *expect_dyn (TyTy::DynamicObjectType *ltype,
126 : TyTy::BaseType *rtype);
127 : TyTy::BaseType *expect_closure (TyTy::ClosureType *ltype,
128 : TyTy::BaseType *rtype);
129 : TyTy::BaseType *expect_opaque (TyTy::OpaqueType *ltype,
130 : TyTy::BaseType *rtype);
131 : TyTy::BaseType *expect_const (TyTy::BaseConstType *ltype,
132 : TyTy::BaseType *rtype);
133 :
134 : private:
135 : UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
136 : location_t locus, bool commit_flag, bool emit_error, bool infer,
137 : bool check_bounds, std::vector<CommitSite> &commits,
138 : std::vector<InferenceSite> &infers, ActiveADTs &active_adts,
139 : bool allow_never_coercion);
140 :
141 : TyTy::BaseType *resolve_subtype (TyTy::TyWithLocation lhs,
142 : TyTy::TyWithLocation rhs);
143 :
144 : void emit_type_mismatch () const;
145 : void emit_abi_mismatch (const TyTy::FnType &expected,
146 : const TyTy::FnType &got) const;
147 :
148 : TyTy::BaseType *go ();
149 :
150 : TyTy::BaseType *get_base ();
151 : TyTy::BaseType *get_other ();
152 :
153 : TyTy::TyWithLocation lhs;
154 : TyTy::TyWithLocation rhs;
155 : location_t locus;
156 : bool commit_flag;
157 : bool emit_error;
158 : bool infer_flag;
159 : bool check_bounds_flag;
160 : bool allow_never_coercion;
161 : std::vector<CommitSite> &commits;
162 : std::vector<InferenceSite> &infers;
163 :
164 : ActiveADTs &active_adts;
165 :
166 : Analysis::Mappings &mappings;
167 : TypeCheckContext &context;
168 : };
169 :
170 : } // namespace Resolver
171 : } // namespace Rust
172 :
173 : #endif // RUST_UNIFY
|