Skip to main content

rustc_builtin_macros/deriving/generic/
ty.rs

1//! A mini version of ast::Ty, which is easier to use, and features an explicit `Self` type to use
2//! when specifying impls to be derived.
3
4use std::iter::once;
5
6pub(crate) use Ty::*;
7use rustc_ast::{self as ast, GenericArg};
8use rustc_expand::base::ExtCtxt;
9use rustc_span::{Ident, Span, Symbol, kw};
10use thin_vec::ThinVec;
11
12pub(crate) fn new_path(cx: &ExtCtxt<'_>, span: Span, path: &[Symbol], params: &[Ty]) -> ast::Path {
13    let idents = path.iter().map(|s| Ident::new(*s, span));
14    let tys = params.iter().map(|t| t.to_ty(cx, span));
15    let params = tys.map(GenericArg::Type).collect();
16
17    let idents = once(Ident::new(kw::DollarCrate, span)).chain(idents).collect();
18    cx.path_all(span, false, idents, params)
19}
20
21/// A type. Supports pointers, Self, literals, unit or an arbitrary AST path.
22#[derive(#[automatically_derived]
impl ::core::clone::Clone for Ty {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Ty::Self_ => Self::Self_,
            Ty::Ref(__self_0, __self_1) =>
                Self::Ref(::core::clone::Clone::clone(__self_0),
                    ::core::clone::Clone::clone(__self_1)),
            Ty::Path(__self_0) =>
                Self::Path(::core::clone::Clone::clone(__self_0)),
            Ty::Unit => Self::Unit,
            Ty::AstTy(__self_0) =>
                Self::AstTy(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone)]
23pub(crate) enum Ty {
24    Self_,
25    /// A reference.
26    Ref(Box<Ty>, ast::Mutability),
27    /// `mod::mod::Type<[lifetime], [Params...]>`, including a plain type
28    /// parameter, and things like `i32`
29    Path(ast::Path),
30    /// For () return types.
31    Unit,
32    /// An arbitrary type.
33    AstTy(Box<ast::Ty>),
34}
35
36pub(crate) fn self_ref() -> Ty {
37    Ref(Box::new(Self_), ast::Mutability::Not)
38}
39
40impl Ty {
41    pub(crate) fn to_ty(&self, cx: &ExtCtxt<'_>, span: Span) -> Box<ast::Ty> {
42        match self {
43            Ref(ty, mutbl) => {
44                let raw_ty = ty.to_ty(cx, span);
45                cx.ty_ref(span, raw_ty, None, *mutbl)
46            }
47            Path(p) => cx.ty_path(p.clone()),
48            Self_ => cx.ty_path(cx.path_ident(span, Ident::new(kw::SelfUpper, span))),
49            Unit => cx.ty(span, ast::TyKind::Tup(ThinVec::new())),
50            AstTy(ty) => ty.clone(),
51        }
52    }
53}