1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 A mini version of ast::Ty, which is easier to use, and features an
13 explicit `Self` type to use when specifying impls to be derived.
17 use ast::{P,Expr,Generics,Ident};
18 use ext::base::ExtCtxt;
19 use ext::build::AstBuilder;
20 use codemap::{Span,respan};
21 use owned_slice::OwnedSlice;
23 /// The types of pointers
26 Borrowed(Option<&'a str>, ast::Mutability), // &['lifetime] [mut]
29 /// A path, e.g. `::std::option::Option::<int>` (global). Has support
30 /// for type parameters and a lifetime.
32 pub path: Vec<&'a str> ,
33 pub lifetime: Option<&'a str>,
34 pub params: Vec<~Ty<'a>> ,
39 pub fn new<'r>(path: Vec<&'r str> ) -> Path<'r> {
40 Path::new_(path, None, Vec::new(), true)
42 pub fn new_local<'r>(path: &'r str) -> Path<'r> {
43 Path::new_(vec!( path ), None, Vec::new(), false)
45 pub fn new_<'r>(path: Vec<&'r str> ,
46 lifetime: Option<&'r str>,
47 params: Vec<~Ty<'r>> ,
62 self_generics: &Generics)
64 cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None)
70 self_generics: &Generics)
72 let idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
73 let lt = mk_lifetimes(cx, span, &self.lifetime);
74 let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
76 cx.path_all(span, self.global, idents, lt, tys)
80 /// A type. Supports pointers (except for *), Self, and literals
84 Ptr(~Ty<'a>, PtrTy<'a>),
85 // mod::mod::Type<[lifetime], [Params...]>, including a plain type
86 // parameter, and things like `int`
92 pub fn borrowed_ptrty<'r>() -> PtrTy<'r> {
93 Borrowed(None, ast::MutImmutable)
95 pub fn borrowed<'r>(ty: ~Ty<'r>) -> Ty<'r> {
96 Ptr(ty, borrowed_ptrty())
99 pub fn borrowed_explicit_self<'r>() -> Option<Option<PtrTy<'r>>> {
100 Some(Some(borrowed_ptrty()))
103 pub fn borrowed_self<'r>() -> Ty<'r> {
107 pub fn nil_ty() -> Ty<'static> {
111 fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option<ast::Lifetime> {
113 Some(ref s) => Some(cx.lifetime(span, cx.ident_of(*s).name)),
118 fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec<ast::Lifetime> {
120 Some(ref s) => vec!(cx.lifetime(span, cx.ident_of(*s).name)),
130 self_generics: &Generics)
133 Ptr(ref ty, ref ptr) => {
134 let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
137 cx.ty_uniq(span, raw_ty)
139 Borrowed(ref lt, mutbl) => {
140 let lt = mk_lifetime(cx, span, lt);
141 cx.ty_rptr(span, raw_ty, lt, mutbl)
145 Literal(ref p) => { p.to_ty(cx, span, self_ty, self_generics) }
147 cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None)
149 Tuple(ref fields) => {
150 let ty = if fields.is_empty() {
153 ast::TyTup(fields.iter()
154 .map(|f| f.to_ty(cx, span, self_ty, self_generics))
163 pub fn to_path(&self,
167 self_generics: &Generics)
171 let self_params = self_generics.ty_params.map(|ty_param| {
172 cx.ty_ident(span, ty_param.ident)
174 let lifetimes = self_generics.lifetimes.clone();
176 cx.path_all(span, false, vec!(self_ty), lifetimes,
177 self_params.into_vec())
180 p.to_path(cx, span, self_ty, self_generics)
182 Ptr(..) => { cx.span_bug(span, "pointer in a path in generic `deriving`") }
183 Tuple(..) => { cx.span_bug(span, "tuple in a path in generic `deriving`") }
189 fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, sized: ast::Sized, bounds: &[Path],
190 self_ident: Ident, self_generics: &Generics) -> ast::TyParam {
192 bounds.iter().map(|b| {
193 let path = b.to_path(cx, span, self_ident, self_generics);
194 cx.typarambound(path)
196 cx.typaram(span, cx.ident_of(name), sized, bounds, None)
199 fn mk_generics(lifetimes: Vec<ast::Lifetime> , ty_params: Vec<ast::TyParam> ) -> Generics {
201 lifetimes: lifetimes,
202 ty_params: OwnedSlice::from_vec(ty_params)
206 /// Lifetimes and bounds on type parameters
207 pub struct LifetimeBounds<'a> {
208 pub lifetimes: Vec<&'a str>,
209 pub bounds: Vec<(&'a str, ast::Sized, Vec<Path<'a>>)>,
212 impl<'a> LifetimeBounds<'a> {
213 pub fn empty() -> LifetimeBounds<'static> {
215 lifetimes: Vec::new(), bounds: Vec::new()
218 pub fn to_generics(&self,
222 self_generics: &Generics)
224 let lifetimes = self.lifetimes.iter().map(|lt| {
225 cx.lifetime(span, cx.ident_of(*lt).name)
227 let ty_params = self.bounds.iter().map(|t| {
229 &(ref name, sized, ref bounds) => {
240 mk_generics(lifetimes, ty_params)
245 pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
246 -> (@Expr, ast::ExplicitSelf) {
247 let self_path = cx.expr_self(span);
250 (self_path, respan(span, ast::SelfValue))
253 let self_ty = respan(
256 Send => ast::SelfUniq,
257 Borrowed(ref lt, mutbl) => {
258 let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
259 ast::SelfRegion(lt, mutbl)
262 let self_expr = cx.expr_deref(span, self_path);