]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/debuginfo/type_names.rs
Improve diagnostics for inaccessible constructors
[rust.git] / src / librustc_trans / debuginfo / type_names.rs
1 // Copyright 2015 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.
4 //
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.
10
11 // Type Names for Debug Info.
12
13 use common::CrateContext;
14 use rustc::hir::def_id::DefId;
15 use rustc::ty::subst::Substs;
16 use rustc::ty::{self, Ty};
17
18 use rustc::hir;
19
20 // Compute the name of the type as it should be stored in debuginfo. Does not do
21 // any caching, i.e. calling the function twice with the same type will also do
22 // the work twice. The `qualified` parameter only affects the first level of the
23 // type name, further levels (i.e. type parameters) are always fully qualified.
24 pub fn compute_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
25                                              t: Ty<'tcx>,
26                                              qualified: bool)
27                                              -> String {
28     let mut result = String::with_capacity(64);
29     push_debuginfo_type_name(cx, t, qualified, &mut result);
30     result
31 }
32
33 // Pushes the name of the type as it should be stored in debuginfo on the
34 // `output` String. See also compute_debuginfo_type_name().
35 pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
36                                           t: Ty<'tcx>,
37                                           qualified: bool,
38                                           output: &mut String) {
39     match t.sty {
40         ty::TyBool => output.push_str("bool"),
41         ty::TyChar => output.push_str("char"),
42         ty::TyStr => output.push_str("str"),
43         ty::TyNever => output.push_str("!"),
44         ty::TyInt(int_ty) => output.push_str(int_ty.ty_to_string()),
45         ty::TyUint(uint_ty) => output.push_str(uint_ty.ty_to_string()),
46         ty::TyFloat(float_ty) => output.push_str(float_ty.ty_to_string()),
47         ty::TyAdt(def, substs) => {
48             push_item_name(cx, def.did, qualified, output);
49             push_type_params(cx, substs, output);
50         },
51         ty::TyTuple(component_types) => {
52             output.push('(');
53             for &component_type in component_types {
54                 push_debuginfo_type_name(cx, component_type, true, output);
55                 output.push_str(", ");
56             }
57             if !component_types.is_empty() {
58                 output.pop();
59                 output.pop();
60             }
61             output.push(')');
62         },
63         ty::TyBox(inner_type) => {
64             output.push_str("Box<");
65             push_debuginfo_type_name(cx, inner_type, true, output);
66             output.push('>');
67         },
68         ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => {
69             output.push('*');
70             match mutbl {
71                 hir::MutImmutable => output.push_str("const "),
72                 hir::MutMutable => output.push_str("mut "),
73             }
74
75             push_debuginfo_type_name(cx, inner_type, true, output);
76         },
77         ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => {
78             output.push('&');
79             if mutbl == hir::MutMutable {
80                 output.push_str("mut ");
81             }
82
83             push_debuginfo_type_name(cx, inner_type, true, output);
84         },
85         ty::TyArray(inner_type, len) => {
86             output.push('[');
87             push_debuginfo_type_name(cx, inner_type, true, output);
88             output.push_str(&format!("; {}", len));
89             output.push(']');
90         },
91         ty::TySlice(inner_type) => {
92             output.push('[');
93             push_debuginfo_type_name(cx, inner_type, true, output);
94             output.push(']');
95         },
96         ty::TyDynamic(ref trait_data, ..) => {
97             if let Some(principal) = trait_data.principal() {
98                 let principal = cx.tcx().erase_late_bound_regions_and_normalize(
99                     &principal);
100                 push_item_name(cx, principal.def_id, false, output);
101                 push_type_params(cx, principal.substs, output);
102             }
103         },
104         ty::TyFnDef(.., &ty::BareFnTy{ unsafety, abi, ref sig } ) |
105         ty::TyFnPtr(&ty::BareFnTy{ unsafety, abi, ref sig } ) => {
106             if unsafety == hir::Unsafety::Unsafe {
107                 output.push_str("unsafe ");
108             }
109
110             if abi != ::abi::Abi::Rust {
111                 output.push_str("extern \"");
112                 output.push_str(abi.name());
113                 output.push_str("\" ");
114             }
115
116             output.push_str("fn(");
117
118             let sig = cx.tcx().erase_late_bound_regions_and_normalize(sig);
119             if !sig.inputs().is_empty() {
120                 for &parameter_type in sig.inputs() {
121                     push_debuginfo_type_name(cx, parameter_type, true, output);
122                     output.push_str(", ");
123                 }
124                 output.pop();
125                 output.pop();
126             }
127
128             if sig.variadic {
129                 if !sig.inputs().is_empty() {
130                     output.push_str(", ...");
131                 } else {
132                     output.push_str("...");
133                 }
134             }
135
136             output.push(')');
137
138             if !sig.output().is_nil() {
139                 output.push_str(" -> ");
140                 push_debuginfo_type_name(cx, sig.output(), true, output);
141             }
142         },
143         ty::TyClosure(..) => {
144             output.push_str("closure");
145         }
146         ty::TyError |
147         ty::TyInfer(_) |
148         ty::TyProjection(..) |
149         ty::TyAnon(..) |
150         ty::TyParam(_) => {
151             bug!("debuginfo: Trying to create type name for \
152                 unexpected type: {:?}", t);
153         }
154     }
155
156     fn push_item_name(cx: &CrateContext,
157                       def_id: DefId,
158                       qualified: bool,
159                       output: &mut String) {
160         if qualified {
161             output.push_str(&cx.tcx().crate_name(def_id.krate).as_str());
162             for path_element in cx.tcx().def_path(def_id).data {
163                 output.push_str("::");
164                 output.push_str(&path_element.data.as_interned_str());
165             }
166         } else {
167             output.push_str(&cx.tcx().item_name(def_id).as_str());
168         }
169     }
170
171     // Pushes the type parameters in the given `Substs` to the output string.
172     // This ignores region parameters, since they can't reliably be
173     // reconstructed for items from non-local crates. For local crates, this
174     // would be possible but with inlining and LTO we have to use the least
175     // common denominator - otherwise we would run into conflicts.
176     fn push_type_params<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
177                                   substs: &Substs<'tcx>,
178                                   output: &mut String) {
179         if substs.types().next().is_none() {
180             return;
181         }
182
183         output.push('<');
184
185         for type_parameter in substs.types() {
186             push_debuginfo_type_name(cx, type_parameter, true, output);
187             output.push_str(", ");
188         }
189
190         output.pop();
191         output.pop();
192
193         output.push('>');
194     }
195 }