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 "rust-derive.h"
20 : : #include "rust-derive-clone.h"
21 : : #include "rust-derive-copy.h"
22 : : #include "rust-derive-debug.h"
23 : : #include "rust-derive-default.h"
24 : : #include "rust-derive-eq.h"
25 : : #include "rust-derive-ord.h"
26 : : #include "rust-derive-partial-eq.h"
27 : : #include "rust-derive-hash.h"
28 : : #include "rust-system.h"
29 : :
30 : : namespace Rust {
31 : : namespace AST {
32 : :
33 : 1046 : DeriveVisitor::DeriveVisitor (location_t loc)
34 : 1046 : : loc (loc), builder (Builder (loc))
35 : 1046 : {}
36 : :
37 : : std::vector<std::unique_ptr<Item>>
38 : 1047 : DeriveVisitor::derive (Item &item, const Attribute &attr,
39 : : BuiltinMacro to_derive)
40 : : {
41 : 1047 : auto loc = attr.get_locus ();
42 : :
43 : 1047 : using Kind = AST::Item::Kind;
44 : 1047 : auto item_kind = item.get_item_kind ();
45 : 1047 : if (item_kind != Kind::Enum && item_kind != Kind::Struct
46 : 4 : && item_kind != Kind::Union)
47 : : {
48 : 1 : rust_error_at (loc,
49 : : "derive may only be applied to structs, enums and unions");
50 : 1 : return {};
51 : : }
52 : :
53 : 1046 : switch (to_derive)
54 : : {
55 : 241 : case BuiltinMacro::Clone:
56 : 241 : return vec (DeriveClone (loc).go (item));
57 : 132 : case BuiltinMacro::Copy:
58 : 132 : return vec (DeriveCopy (loc).go (item));
59 : 175 : case BuiltinMacro::Debug:
60 : 175 : rust_warning_at (
61 : : loc, 0,
62 : : "derive(Debug) is not fully implemented yet and has no effect - only a "
63 : : "stub implementation will be generated");
64 : 175 : return vec (DeriveDebug (loc).go (item));
65 : 27 : case BuiltinMacro::Default:
66 : 27 : return vec (DeriveDefault (loc).go (item));
67 : 105 : case BuiltinMacro::Eq:
68 : 105 : return DeriveEq (loc).go (item);
69 : 204 : case BuiltinMacro::PartialEq:
70 : 204 : return DerivePartialEq (loc).go (item);
71 : 37 : case BuiltinMacro::Hash:
72 : 37 : return vec (DeriveHash (loc).go (item));
73 : 62 : case BuiltinMacro::Ord:
74 : 62 : return vec (DeriveOrd (DeriveOrd::Ordering::Total, loc).go (item));
75 : 63 : case BuiltinMacro::PartialOrd:
76 : 63 : return vec (DeriveOrd (DeriveOrd::Ordering::Partial, loc).go (item));
77 : 0 : default:
78 : 0 : rust_unreachable ();
79 : : };
80 : : }
81 : :
82 : : DeriveVisitor::ImplGenerics
83 : 1355 : DeriveVisitor::setup_impl_generics (
84 : : const std::string &type_name,
85 : : const std::vector<std::unique_ptr<GenericParam>> &type_generics,
86 : : tl::optional<std::unique_ptr<TypeParamBound>> &&extra_bound) const
87 : : {
88 : 1355 : std::vector<Lifetime> lifetime_args;
89 : 1355 : std::vector<GenericArg> generic_args;
90 : 1355 : std::vector<std::unique_ptr<GenericParam>> impl_generics;
91 : 1690 : for (const auto &generic : type_generics)
92 : : {
93 : 335 : switch (generic->get_kind ())
94 : : {
95 : 93 : case GenericParam::Kind::Lifetime:
96 : 93 : {
97 : 93 : LifetimeParam &lifetime_param = (LifetimeParam &) *generic.get ();
98 : :
99 : 93 : Lifetime l = builder.new_lifetime (lifetime_param.get_lifetime ());
100 : 93 : lifetime_args.push_back (std::move (l));
101 : :
102 : 93 : auto impl_lifetime_param
103 : 93 : = builder.new_lifetime_param (lifetime_param);
104 : 93 : impl_generics.push_back (std::move (impl_lifetime_param));
105 : 93 : }
106 : 93 : break;
107 : :
108 : 237 : case GenericParam::Kind::Type:
109 : 237 : {
110 : 237 : TypeParam &type_param = (TypeParam &) *generic.get ();
111 : :
112 : 237 : std::unique_ptr<Type> associated_type = builder.single_type_path (
113 : 474 : type_param.get_type_representation ().as_string ());
114 : :
115 : 237 : GenericArg type_arg
116 : 237 : = GenericArg::create_type (std::move (associated_type));
117 : 237 : generic_args.push_back (std::move (type_arg));
118 : :
119 : 237 : std::vector<std::unique_ptr<TypeParamBound>> extra_bounds;
120 : :
121 : 237 : if (extra_bound)
122 : 410 : extra_bounds.emplace_back (
123 : 205 : extra_bound.value ()->clone_type_param_bound ());
124 : :
125 : 237 : auto impl_type_param
126 : 237 : = builder.new_type_param (type_param, std::move (extra_bounds));
127 : :
128 : 237 : impl_generics.push_back (std::move (impl_type_param));
129 : 237 : }
130 : 237 : break;
131 : :
132 : 5 : case GenericParam::Kind::Const:
133 : 5 : {
134 : 5 : ConstGenericParam &const_param
135 : 5 : = (ConstGenericParam &) *generic.get ();
136 : :
137 : 5 : std::unique_ptr<Type> associated_type
138 : 10 : = builder.single_type_path (const_param.get_name ().as_string ());
139 : :
140 : 5 : GenericArg type_arg
141 : 5 : = GenericArg::create_type (std::move (associated_type));
142 : 5 : generic_args.push_back (std::move (type_arg));
143 : :
144 : 5 : auto impl_const_param = builder.new_const_param (const_param);
145 : 5 : impl_generics.push_back (std::move (impl_const_param));
146 : 5 : }
147 : 5 : break;
148 : : }
149 : : }
150 : :
151 : 1355 : auto generic_args_for_self
152 : 1355 : = GenericArgs (lifetime_args, generic_args, {} /*binding args*/, loc);
153 : :
154 : 1355 : std::unique_ptr<Type> self_type_path
155 : 1355 : = impl_generics.empty ()
156 : 2447 : ? builder.single_type_path (type_name)
157 : 4065 : : builder.single_generic_type_path (type_name, generic_args_for_self);
158 : :
159 : 1355 : return ImplGenerics{std::move (self_type_path), std::move (impl_generics)};
160 : 1355 : }
161 : :
162 : : } // namespace AST
163 : : } // namespace Rust
|