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
));