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 : :
29 : : namespace Rust {
30 : : namespace AST {
31 : :
32 : 286 : DeriveVisitor::DeriveVisitor (location_t loc)
33 : 286 : : loc (loc), builder (Builder (loc))
34 : 286 : {}
35 : :
36 : : std::vector<std::unique_ptr<Item>>
37 : 286 : DeriveVisitor::derive (Item &item, const Attribute &attr,
38 : : BuiltinMacro to_derive)
39 : : {
40 : 286 : auto loc = attr.get_locus ();
41 : :
42 : 286 : switch (to_derive)
43 : : {
44 : 38 : case BuiltinMacro::Clone:
45 : 38 : return vec (DeriveClone (loc).go (item));
46 : 15 : case BuiltinMacro::Copy:
47 : 15 : return vec (DeriveCopy (loc).go (item));
48 : 3 : case BuiltinMacro::Debug:
49 : 3 : rust_warning_at (
50 : : loc, 0,
51 : : "derive(Debug) is not fully implemented yet and has no effect - only a "
52 : : "stub implementation will be generated");
53 : 3 : return vec (DeriveDebug (loc).go (item));
54 : 15 : case BuiltinMacro::Default:
55 : 15 : return vec (DeriveDefault (loc).go (item));
56 : 45 : case BuiltinMacro::Eq:
57 : 45 : return DeriveEq (loc).go (item);
58 : 92 : case BuiltinMacro::PartialEq:
59 : 92 : return DerivePartialEq (loc).go (item);
60 : 3 : case BuiltinMacro::Hash:
61 : 3 : return vec (DeriveHash (loc).go (item));
62 : 37 : case BuiltinMacro::Ord:
63 : 37 : return vec (DeriveOrd (DeriveOrd::Ordering::Total, loc).go (item));
64 : 38 : case BuiltinMacro::PartialOrd:
65 : 38 : return vec (DeriveOrd (DeriveOrd::Ordering::Partial, loc).go (item));
66 : 0 : default:
67 : 0 : rust_unreachable ();
68 : : };
69 : : }
70 : :
71 : : DeriveVisitor::ImplGenerics
72 : 423 : DeriveVisitor::setup_impl_generics (
73 : : const std::string &type_name,
74 : : const std::vector<std::unique_ptr<GenericParam>> &type_generics,
75 : : tl::optional<std::unique_ptr<TypeParamBound>> &&extra_bound) const
76 : : {
77 : 423 : std::vector<Lifetime> lifetime_args;
78 : 423 : std::vector<GenericArg> generic_args;
79 : 423 : std::vector<std::unique_ptr<GenericParam>> impl_generics;
80 : 425 : for (const auto &generic : type_generics)
81 : : {
82 : 2 : switch (generic->get_kind ())
83 : : {
84 : 0 : case GenericParam::Kind::Lifetime:
85 : 0 : {
86 : 0 : LifetimeParam &lifetime_param = (LifetimeParam &) *generic.get ();
87 : :
88 : 0 : Lifetime l = builder.new_lifetime (lifetime_param.get_lifetime ());
89 : 0 : lifetime_args.push_back (std::move (l));
90 : :
91 : 0 : auto impl_lifetime_param
92 : 0 : = builder.new_lifetime_param (lifetime_param);
93 : 0 : impl_generics.push_back (std::move (impl_lifetime_param));
94 : 0 : }
95 : 0 : break;
96 : :
97 : 2 : case GenericParam::Kind::Type:
98 : 2 : {
99 : 2 : TypeParam &type_param = (TypeParam &) *generic.get ();
100 : :
101 : 2 : std::unique_ptr<Type> associated_type = builder.single_type_path (
102 : 4 : type_param.get_type_representation ().as_string ());
103 : :
104 : 2 : GenericArg type_arg
105 : 2 : = GenericArg::create_type (std::move (associated_type));
106 : 2 : generic_args.push_back (std::move (type_arg));
107 : :
108 : 2 : std::vector<std::unique_ptr<TypeParamBound>> extra_bounds;
109 : :
110 : 2 : if (extra_bound)
111 : 4 : extra_bounds.emplace_back (
112 : 2 : extra_bound.value ()->clone_type_param_bound ());
113 : :
114 : 2 : auto impl_type_param
115 : 2 : = builder.new_type_param (type_param, std::move (extra_bounds));
116 : :
117 : 2 : impl_generics.push_back (std::move (impl_type_param));
118 : 2 : }
119 : 2 : break;
120 : :
121 : 0 : case GenericParam::Kind::Const:
122 : 0 : {
123 : 0 : ConstGenericParam &const_param
124 : 0 : = (ConstGenericParam &) *generic.get ();
125 : :
126 : 0 : std::unique_ptr<Type> associated_type
127 : 0 : = builder.single_type_path (const_param.get_name ().as_string ());
128 : :
129 : 0 : GenericArg type_arg
130 : 0 : = GenericArg::create_type (std::move (associated_type));
131 : 0 : generic_args.push_back (std::move (type_arg));
132 : :
133 : 0 : auto impl_const_param = builder.new_const_param (const_param);
134 : 0 : impl_generics.push_back (std::move (impl_const_param));
135 : 0 : }
136 : 0 : break;
137 : : }
138 : : }
139 : :
140 : 423 : auto generic_args_for_self
141 : 423 : = GenericArgs (lifetime_args, generic_args, {} /*binding args*/, loc);
142 : :
143 : 423 : std::unique_ptr<Type> self_type_path
144 : 423 : = impl_generics.empty ()
145 : 844 : ? builder.single_type_path (type_name)
146 : 1269 : : builder.single_generic_type_path (type_name, generic_args_for_self);
147 : :
148 : 423 : return ImplGenerics{std::move (self_type_path), std::move (impl_generics)};
149 : 423 : }
150 : :
151 : : } // namespace AST
152 : : } // namespace Rust
|