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.
7 use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind};
8 use rustc_expand::base::ExtCtxt;
9 use rustc_span::source_map::{respan, DUMMY_SP};
10 use rustc_span::symbol::{kw, Ident, Symbol};
13 /// A path, e.g., `::std::option::Option::<i32>` (global). Has support
14 /// for type parameters.
30 pub fn new(path: Vec<Symbol>) -> Path {
31 Path::new_(path, Vec::new(), PathKind::Std)
33 pub fn new_local(path: Symbol) -> Path {
34 Path::new_(vec![path], Vec::new(), PathKind::Local)
36 pub fn new_(path: Vec<Symbol>, params: Vec<Box<Ty>>, kind: PathKind) -> Path {
37 Path { path, params, kind }
45 self_generics: &Generics,
47 cx.ty_path(self.to_path(cx, span, self_ty, self_generics))
54 self_generics: &Generics,
56 let mut idents = self.path.iter().map(|s| Ident::new(*s, span)).collect();
57 let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics));
58 let params = tys.map(GenericArg::Type).collect();
61 PathKind::Global => cx.path_all(span, true, idents, params),
62 PathKind::Local => cx.path_all(span, false, idents, params),
64 let def_site = cx.with_def_site_ctxt(DUMMY_SP);
65 idents.insert(0, Ident::new(kw::DollarCrate, def_site));
66 cx.path_all(span, false, idents, params)
72 /// A type. Supports pointers, Self, and literals.
77 Ref(Box<Ty>, ast::Mutability),
78 /// `mod::mod::Type<[lifetime], [Params...]>`, including a plain type
79 /// parameter, and things like `i32`
81 /// For () return types.
85 pub fn self_ref() -> Ty {
86 Ref(Box::new(Self_), ast::Mutability::Not)
95 self_generics: &Generics,
99 let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
100 cx.ty_ref(span, raw_ty, None, *mutbl)
102 Path(p) => p.to_ty(cx, span, self_ty, self_generics),
103 Self_ => cx.ty_path(self.to_path(cx, span, self_ty, self_generics)),
105 let ty = ast::TyKind::Tup(vec![]);
120 let params: Vec<_> = generics
123 .map(|param| match param.kind {
124 GenericParamKind::Lifetime { .. } => {
125 GenericArg::Lifetime(ast::Lifetime { id: param.id, ident: param.ident })
127 GenericParamKind::Type { .. } => {
128 GenericArg::Type(cx.ty_ident(span, param.ident))
130 GenericParamKind::Const { .. } => {
131 GenericArg::Const(cx.const_ident(span, param.ident))
136 cx.path_all(span, false, vec![self_ty], params)
138 Path(p) => p.to_path(cx, span, self_ty, generics),
139 Ref(..) => cx.span_bug(span, "ref in a path in generic `derive`"),
140 Unit => cx.span_bug(span, "unit in a path in generic `derive`"),
151 self_generics: &Generics,
152 ) -> ast::GenericParam {
156 let path = b.to_path(cx, span, self_ident, self_generics);
160 cx.typaram(span, Ident::new(name, span), bounds, None)
163 /// Bounds on type parameters.
166 pub bounds: Vec<(Symbol, Vec<Path>)>,
170 pub fn empty() -> Bounds {
171 Bounds { bounds: Vec::new() }
178 self_generics: &Generics,
183 .map(|&(name, ref bounds)| mk_ty_param(cx, span, name, &bounds, self_ty, self_generics))
188 where_clause: ast::WhereClause { has_where_token: false, predicates: Vec::new(), span },
194 pub fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (P<Expr>, ast::ExplicitSelf) {
195 // This constructs a fresh `self` path.
196 let self_path = cx.expr_self(span);
197 let self_ty = respan(span, SelfKind::Region(None, ast::Mutability::Not));