rustc_builtin_macros/deriving/generic/
ty.rs1pub(crate) use Ty::*;
5use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind, TyKind};
6use rustc_expand::base::ExtCtxt;
7use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, respan};
8use thin_vec::ThinVec;
9
10#[derive(#[automatically_derived]
impl ::core::clone::Clone for Path {
#[inline]
fn clone(&self) -> Path {
Path {
path: ::core::clone::Clone::clone(&self.path),
params: ::core::clone::Clone::clone(&self.params),
kind: ::core::clone::Clone::clone(&self.kind),
}
}
}Clone)]
13pub(crate) struct Path {
14 path: Vec<Symbol>,
15 params: Vec<Box<Ty>>,
16 kind: PathKind,
17}
18
19#[derive(#[automatically_derived]
impl ::core::clone::Clone for PathKind {
#[inline]
fn clone(&self) -> PathKind {
match self {
PathKind::Local => PathKind::Local,
PathKind::Std => PathKind::Std,
}
}
}Clone)]
20pub(crate) enum PathKind {
21 Local,
22 Std,
23}
24
25impl Path {
26 pub(crate) fn new(path: Vec<Symbol>) -> Path {
27 Path::new_(path, Vec::new(), PathKind::Std)
28 }
29 pub(crate) fn new_local(path: Symbol) -> Path {
30 Path::new_(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[path]))vec![path], Vec::new(), PathKind::Local)
31 }
32 pub(crate) fn new_(path: Vec<Symbol>, params: Vec<Box<Ty>>, kind: PathKind) -> Path {
33 Path { path, params, kind }
34 }
35
36 pub(crate) fn to_ty(
37 &self,
38 cx: &ExtCtxt<'_>,
39 span: Span,
40 self_ty: Ident,
41 self_generics: &Generics,
42 ) -> Box<ast::Ty> {
43 cx.ty_path(self.to_path(cx, span, self_ty, self_generics))
44 }
45 pub(crate) fn to_path(
46 &self,
47 cx: &ExtCtxt<'_>,
48 span: Span,
49 self_ty: Ident,
50 self_generics: &Generics,
51 ) -> ast::Path {
52 let mut idents = self.path.iter().map(|s| Ident::new(*s, span)).collect();
53 let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics));
54 let params = tys.map(GenericArg::Type).collect();
55
56 match self.kind {
57 PathKind::Local => cx.path_all(span, false, idents, params),
58 PathKind::Std => {
59 let def_site = cx.with_def_site_ctxt(DUMMY_SP);
60 idents.insert(0, Ident::new(kw::DollarCrate, def_site));
61 cx.path_all(span, false, idents, params)
62 }
63 }
64 }
65}
66
67#[derive(#[automatically_derived]
impl ::core::clone::Clone for Ty {
#[inline]
fn clone(&self) -> Ty {
match self {
Ty::Self_ => Ty::Self_,
Ty::Ref(__self_0, __self_1) =>
Ty::Ref(::core::clone::Clone::clone(__self_0),
::core::clone::Clone::clone(__self_1)),
Ty::Path(__self_0) =>
Ty::Path(::core::clone::Clone::clone(__self_0)),
Ty::Unit => Ty::Unit,
Ty::AstTy(__self_0) =>
Ty::AstTy(::core::clone::Clone::clone(__self_0)),
}
}
}Clone)]
69pub(crate) enum Ty {
70 Self_,
71 Ref(Box<Ty>, ast::Mutability),
73 Path(Path),
76 Unit,
78 AstTy(Box<ast::Ty>),
80}
81
82pub(crate) fn self_ref() -> Ty {
83 Ref(Box::new(Self_), ast::Mutability::Not)
84}
85
86impl Ty {
87 pub(crate) fn to_ty(
88 &self,
89 cx: &ExtCtxt<'_>,
90 span: Span,
91 self_ty: Ident,
92 self_generics: &Generics,
93 ) -> Box<ast::Ty> {
94 match self {
95 Ref(ty, mutbl) => {
96 let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
97 cx.ty_ref(span, raw_ty, None, *mutbl)
98 }
99 Path(p) => p.to_ty(cx, span, self_ty, self_generics),
100 Self_ => cx.ty_path(self.to_path(cx, span, self_ty, self_generics)),
101 Unit => {
102 let ty = ast::TyKind::Tup(ThinVec::new());
103 cx.ty(span, ty)
104 }
105 AstTy(ty) => ty.clone(),
106 }
107 }
108
109 pub(crate) fn to_path(
110 &self,
111 cx: &ExtCtxt<'_>,
112 span: Span,
113 self_ty: Ident,
114 generics: &Generics,
115 ) -> ast::Path {
116 match self {
117 Self_ => {
118 let params: Vec<_> = generics
119 .params
120 .iter()
121 .map(|param| match param.kind {
122 GenericParamKind::Lifetime { .. } => {
123 GenericArg::Lifetime(ast::Lifetime { id: param.id, ident: param.ident })
124 }
125 GenericParamKind::Type { .. } => {
126 GenericArg::Type(cx.ty_ident(span, param.ident))
127 }
128 GenericParamKind::Const { .. } => {
129 GenericArg::Const(cx.const_ident(span, param.ident))
130 }
131 })
132 .collect();
133
134 cx.path_all(span, false, ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[self_ty]))vec![self_ty], params)
135 }
136 Path(p) => p.to_path(cx, span, self_ty, generics),
137 AstTy(ty) => match &ty.kind {
138 TyKind::Path(_, path) => path.clone(),
139 _ => cx.dcx().span_bug(span, "non-path in a path in generic `derive`"),
140 },
141 Ref(..) => cx.dcx().span_bug(span, "ref in a path in generic `derive`"),
142 Unit => cx.dcx().span_bug(span, "unit in a path in generic `derive`"),
143 }
144 }
145}
146
147fn mk_ty_param(
148 cx: &ExtCtxt<'_>,
149 span: Span,
150 name: Symbol,
151 bounds: &[Path],
152 self_ident: Ident,
153 self_generics: &Generics,
154) -> ast::GenericParam {
155 let bounds = bounds
156 .iter()
157 .map(|b| {
158 let path = b.to_path(cx, span, self_ident, self_generics);
159 cx.trait_bound(path, false)
160 })
161 .collect();
162 cx.typaram(span, Ident::new(name, span), bounds, None)
163}
164
165#[derive(#[automatically_derived]
impl ::core::clone::Clone for Bounds {
#[inline]
fn clone(&self) -> Bounds {
Bounds { bounds: ::core::clone::Clone::clone(&self.bounds) }
}
}Clone)]
167pub(crate) struct Bounds {
168 pub bounds: Vec<(Symbol, Vec<Path>)>,
169}
170
171impl Bounds {
172 pub(crate) fn empty() -> Bounds {
173 Bounds { bounds: Vec::new() }
174 }
175 pub(crate) fn to_generics(
176 &self,
177 cx: &ExtCtxt<'_>,
178 span: Span,
179 self_ty: Ident,
180 self_generics: &Generics,
181 ) -> Generics {
182 let params = self
183 .bounds
184 .iter()
185 .map(|&(name, ref bounds)| mk_ty_param(cx, span, name, bounds, self_ty, self_generics))
186 .collect();
187
188 Generics {
189 params,
190 where_clause: ast::WhereClause {
191 has_where_token: false,
192 predicates: ThinVec::new(),
193 span,
194 },
195 span,
196 }
197 }
198}
199
200pub(crate) fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (Box<Expr>, ast::ExplicitSelf) {
201 let self_path = cx.expr_self(span);
203 let self_ty = respan(span, SelfKind::Region(None, ast::Mutability::Not));
204 (self_path, self_ty)
205}