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