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 : : #ifndef RUST_AUTODEREF
20 : : #define RUST_AUTODEREF
21 : :
22 : : #include "rust-tyty.h"
23 : :
24 : : namespace Rust {
25 : : namespace Resolver {
26 : :
27 : : class Adjustment
28 : : {
29 : : public:
30 : : enum AdjustmentType
31 : : {
32 : : ERROR,
33 : :
34 : : IMM_REF,
35 : : MUT_REF,
36 : : DEREF,
37 : : DEREF_MUT,
38 : : INDIRECTION,
39 : : UNSIZE,
40 : : };
41 : :
42 : : // ctor for all adjustments except derefs
43 : 6905 : Adjustment (AdjustmentType type, TyTy::BaseType *actual,
44 : : TyTy::BaseType *expected)
45 : 6905 : : Adjustment (type, actual, expected, nullptr, AdjustmentType::ERROR)
46 : 144 : {}
47 : :
48 : 79 : static Adjustment get_op_overload_deref_adjustment (
49 : : AdjustmentType type, TyTy::BaseType *actual, TyTy::BaseType *expected,
50 : : TyTy::FnType *fn, Adjustment::AdjustmentType requires_ref_adjustment)
51 : : {
52 : 79 : rust_assert (type == DEREF || type == DEREF_MUT);
53 : 79 : return Adjustment (type, actual, expected, fn, requires_ref_adjustment);
54 : : }
55 : :
56 : 695 : AdjustmentType get_type () const { return type; }
57 : :
58 : 126 : TyTy::BaseType *get_actual () const { return actual; }
59 : 872 : TyTy::BaseType *get_expected () const { return expected; }
60 : :
61 : : std::string as_string () const
62 : : {
63 : : return Adjustment::type_string (get_type ()) + "->"
64 : : + get_expected ()->debug_str ();
65 : : }
66 : :
67 : : static std::string type_string (AdjustmentType type)
68 : : {
69 : : switch (type)
70 : : {
71 : : case AdjustmentType::ERROR:
72 : : return "ERROR";
73 : : case AdjustmentType::IMM_REF:
74 : : return "IMM_REF";
75 : : case AdjustmentType::MUT_REF:
76 : : return "MUT_REF";
77 : : case AdjustmentType::DEREF:
78 : : return "DEREF";
79 : : case AdjustmentType::DEREF_MUT:
80 : : return "DEREF_MUT";
81 : : case AdjustmentType::INDIRECTION:
82 : : return "INDIRECTION";
83 : : case AdjustmentType::UNSIZE:
84 : : return "UNSIZE";
85 : : }
86 : : rust_unreachable ();
87 : : return "";
88 : : }
89 : :
90 : 350 : static Adjustment get_error () { return Adjustment{ERROR, nullptr, nullptr}; }
91 : :
92 : 566 : bool is_error () const { return type == ERROR; }
93 : :
94 : 56 : bool is_deref_adjustment () const { return type == DEREF; }
95 : :
96 : : bool is_deref_mut_adjustment () const { return type == DEREF_MUT; }
97 : :
98 : 56 : bool has_operator_overload () const { return deref_operator_fn != nullptr; }
99 : :
100 : : TyTy::FnType *get_deref_operator_fn () const { return deref_operator_fn; }
101 : :
102 : 56 : AdjustmentType get_deref_adjustment_type () const
103 : : {
104 : 56 : return requires_ref_adjustment;
105 : : }
106 : :
107 : : private:
108 : 6984 : Adjustment (AdjustmentType type, TyTy::BaseType *actual,
109 : : TyTy::BaseType *expected, TyTy::FnType *deref_operator_fn,
110 : : Adjustment::AdjustmentType requires_ref_adjustment)
111 : 6984 : : type (type), actual (actual), expected (expected),
112 : 6984 : deref_operator_fn (deref_operator_fn),
113 : 6984 : requires_ref_adjustment (requires_ref_adjustment)
114 : : {}
115 : :
116 : : AdjustmentType type;
117 : : TyTy::BaseType *actual;
118 : : TyTy::BaseType *expected;
119 : :
120 : : // - only used for deref operator_overloads
121 : : //
122 : : // the fn that we are calling
123 : : TyTy::FnType *deref_operator_fn;
124 : : // operator overloads can requre a reference
125 : : Adjustment::AdjustmentType requires_ref_adjustment;
126 : : };
127 : :
128 : : class Adjuster
129 : : {
130 : : public:
131 : 1637 : Adjuster (const TyTy::BaseType *ty) : base (ty) {}
132 : :
133 : : TyTy::BaseType *adjust_type (const std::vector<Adjustment> &adjustments);
134 : :
135 : : static Adjustment try_deref_type (TyTy::BaseType *ty,
136 : : LangItem::Kind deref_lang_item);
137 : :
138 : : static Adjustment try_raw_deref_type (TyTy::BaseType *ty);
139 : :
140 : : static Adjustment try_unsize_type (TyTy::BaseType *ty);
141 : :
142 : : private:
143 : : const TyTy::BaseType *base;
144 : : };
145 : :
146 : : class AutoderefCycle
147 : : {
148 : : protected:
149 : : AutoderefCycle (bool autoderef_flag);
150 : :
151 : : virtual ~AutoderefCycle ();
152 : :
153 : : virtual bool select (TyTy::BaseType &autoderefed) = 0;
154 : :
155 : : // optional: this is a chance to hook in to grab predicate items on the raw
156 : : // type
157 : : virtual void try_hook (const TyTy::BaseType &);
158 : :
159 : : virtual bool cycle (TyTy::BaseType *receiver);
160 : :
161 : : bool try_autoderefed (TyTy::BaseType *r);
162 : :
163 : : bool autoderef_flag;
164 : : std::vector<Adjustment> adjustments;
165 : : };
166 : :
167 : : } // namespace Resolver
168 : : } // namespace Rust
169 : :
170 : : #endif // RUST_AUTODEREF
|