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_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 25345 : Adjustment (AdjustmentType type, TyTy::BaseType *actual,
44 : TyTy::BaseType *expected)
45 25345 : : Adjustment (type, actual, expected, nullptr, AdjustmentType::ERROR)
46 231 : {}
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 2219 : AdjustmentType get_type () const { return type; }
57 :
58 180 : TyTy::BaseType *get_actual () const { return actual; }
59 2541 : 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 782 : static Adjustment get_error () { return Adjustment{ERROR, nullptr, nullptr}; }
91 :
92 1195 : 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 25424 : Adjustment (AdjustmentType type, TyTy::BaseType *actual,
109 : TyTy::BaseType *expected, TyTy::FnType *deref_operator_fn,
110 : Adjustment::AdjustmentType requires_ref_adjustment)
111 25424 : : type (type), actual (actual), expected (expected),
112 25424 : deref_operator_fn (deref_operator_fn),
113 25424 : 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 4521 : 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
|