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.
8 use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind};
9 use rustc_expand::base::ExtCtxt;
10 use rustc_span::source_map::{respan, DUMMY_SP};
11 use rustc_span::symbol::{kw, Ident, Symbol};
14 /// The types of pointers
18 Borrowed(Option<Ident>, ast::Mutability),
24 /// A path, e.g., `::std::option::Option::<i32>` (global). Has support
25 /// for type parameters and a lifetime.
29 lifetime: Option<Ident>,
42 pub fn new(path: Vec<Symbol>) -> Path {
43 Path::new_(path, None, Vec::new(), PathKind::Std)
45 pub fn new_local(path: Symbol) -> Path {
46 Path::new_(vec![path], None, Vec::new(), PathKind::Local)
50 lifetime: Option<Ident>,
54 Path { path, lifetime, params, kind }
62 self_generics: &Generics,
64 cx.ty_path(self.to_path(cx, span, self_ty, self_generics))
71 self_generics: &Generics,
73 let mut idents = self.path.iter().map(|s| Ident::new(*s, span)).collect();
74 let lt = mk_lifetimes(cx, span, &self.lifetime);
75 let tys: Vec<P<ast::Ty>> =
76 self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
79 .map(GenericArg::Lifetime)
80 .chain(tys.into_iter().map(GenericArg::Type))
84 PathKind::Global => cx.path_all(span, true, idents, params),
85 PathKind::Local => cx.path_all(span, false, idents, params),
87 let def_site = cx.with_def_site_ctxt(DUMMY_SP);
88 idents.insert(0, Ident::new(kw::DollarCrate, def_site));
89 cx.path_all(span, false, idents, params)
95 /// A type. Supports pointers, Self, and literals.
101 /// `mod::mod::Type<[lifetime], [Params...]>`, including a plain type
102 /// parameter, and things like `i32`
108 pub fn borrowed_ptrty() -> PtrTy {
109 Borrowed(None, ast::Mutability::Not)
111 pub fn borrowed(ty: Box<Ty>) -> Ty {
112 Ptr(ty, borrowed_ptrty())
115 pub fn borrowed_explicit_self() -> Option<Option<PtrTy>> {
116 Some(Some(borrowed_ptrty()))
119 pub fn borrowed_self() -> Ty {
120 borrowed(Box::new(Self_))
123 pub fn nil_ty() -> Ty {
127 fn mk_lifetime(cx: &ExtCtxt<'_>, span: Span, lt: &Option<Ident>) -> Option<ast::Lifetime> {
128 lt.map(|ident| cx.lifetime(span, ident))
131 fn mk_lifetimes(cx: &ExtCtxt<'_>, span: Span, lt: &Option<Ident>) -> Vec<ast::Lifetime> {
132 mk_lifetime(cx, span, lt).into_iter().collect()
141 self_generics: &Generics,
144 Ptr(ref ty, ref ptr) => {
145 let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
147 Borrowed(ref lt, mutbl) => {
148 let lt = mk_lifetime(cx, span, lt);
149 cx.ty_rptr(span, raw_ty, lt, mutbl)
151 Raw(mutbl) => cx.ty_ptr(span, raw_ty, mutbl),
154 Literal(ref p) => p.to_ty(cx, span, self_ty, self_generics),
155 Self_ => cx.ty_path(self.to_path(cx, span, self_ty, self_generics)),
156 Tuple(ref fields) => {
157 let ty = ast::TyKind::Tup(
158 fields.iter().map(|f| f.to_ty(cx, span, self_ty, self_generics)).collect(),
174 let params: Vec<_> = generics
177 .map(|param| match param.kind {
178 GenericParamKind::Lifetime { .. } => {
179 GenericArg::Lifetime(ast::Lifetime { id: param.id, ident: param.ident })
181 GenericParamKind::Type { .. } => {
182 GenericArg::Type(cx.ty_ident(span, param.ident))
184 GenericParamKind::Const { .. } => {
185 GenericArg::Const(cx.const_ident(span, param.ident))
190 cx.path_all(span, false, vec![self_ty], params)
192 Literal(ref p) => p.to_path(cx, span, self_ty, generics),
193 Ptr(..) => cx.span_bug(span, "pointer in a path in generic `derive`"),
194 Tuple(..) => cx.span_bug(span, "tuple in a path in generic `derive`"),
203 attrs: &[ast::Attribute],
206 self_generics: &Generics,
207 ) -> ast::GenericParam {
211 let path = b.to_path(cx, span, self_ident, self_generics);
215 cx.typaram(span, Ident::new(name, span), attrs.to_owned(), bounds, None)
218 fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
221 where_clause: ast::WhereClause { has_where_token: false, predicates: Vec::new(), span },
226 /// Bounds on type parameters.
229 pub bounds: Vec<(Symbol, Vec<Path>)>,
233 pub fn empty() -> Bounds {
234 Bounds { bounds: Vec::new() }
241 self_generics: &Generics,
243 let generic_params = self
247 let (name, ref bounds) = *t;
248 mk_ty_param(cx, span, name, &[], &bounds, self_ty, self_generics)
252 mk_generics(generic_params, span)
256 pub fn get_explicit_self(
259 self_ptr: &Option<PtrTy>,
260 ) -> (P<Expr>, ast::ExplicitSelf) {
261 // this constructs a fresh `self` path
262 let self_path = cx.expr_self(span);
264 None => (self_path, respan(span, SelfKind::Value(ast::Mutability::Not))),
266 let self_ty = respan(
269 Borrowed(ref lt, mutbl) => {
270 let lt = lt.map(|s| cx.lifetime(span, s));
271 SelfKind::Region(lt, mutbl)
273 Raw(_) => cx.span_bug(span, "attempted to use *self in deriving definition"),
276 let self_expr = cx.expr_deref(span, self_path);