1 // Copyright 2012-2014 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 /*
12
13 typeck.rs, an introduction
14
15 The type checker is responsible for:
16
17 1. Determining the type of each expression
18 2. Resolving methods and traits
19 3. Guaranteeing that most type rules are met ("most?", you say, "why most?"
20 Well, dear reader, read on)
21
22 The main entry point is `check_crate()`. Type checking operates in
23 several major phases:
24
25 1. The collect phase first passes over all items and determines their
26 type, without examining their "innards".
27
28 2. Variance inference then runs to compute the variance of each parameter
29
30 3. Coherence checks for overlapping or orphaned impls
31
32 4. Finally, the check phase then checks function bodies and so forth.
33 Within the check phase, we check each function body one at a time
34 (bodies of function expressions are checked as part of the
35 containing function). Inference is used to supply types wherever
36 they are unknown. The actual checking of a function itself has
37 several phases (check, regionck, writeback), as discussed in the
38 documentation for the `check` module.
39
40 The type checker is defined into various submodules which are documented
41 independently:
42
43 - astconv: converts the AST representation of types
44 into the `ty` representation
45
46 - collect: computes the types of each top-level item and enters them into
47 the `cx.tcache` table for later use
48
49 - coherence: enforces coherence rules, builds some tables
50
51 - variance: variance inference
52
53 - check: walks over function bodies and type checks them, inferring types for
54 local variables, type parameters, etc as necessary.
55
56 - infer: finds the types to use for each type variable such that
57 all subtyping and assignment constraints are met. In essence, the check
58 module specifies the constraints, and the infer module solves them.
59
60 */
61
62 #![allow(non_camel_case_types)]
63
64 use driver::session;
65
66 use middle::resolve;
67 use middle::ty;
68 use util::common::time;
69 use util::ppaux::Repr;
70 use util::ppaux;
71 use util::nodemap::{DefIdMap, FnvHashMap};
72
73 use std::cell::RefCell;
74 use std::rc::Rc;
75 use syntax::codemap::Span;
76 use syntax::print::pprust::*;
77 use syntax::{ast, ast_map, abi};
78
79 pub mod check;
80 pub mod rscope;
81 pub mod astconv;
82 pub mod infer;
83 pub mod collect;
84 pub mod coherence;
85 pub mod variance;
86
87 #[deriving(Clone, Encodable, Decodable, Eq, Ord)]
88 pub enum param_index {
89 param_numbered(uint),
90 param_self
91 }
92
93 #[deriving(Clone, Encodable, Decodable)]
94 pub enum MethodOrigin {
95 // fully statically resolved method
96 MethodStatic(ast::DefId),
97
98 // method invoked on a type parameter with a bounded trait
99 MethodParam(MethodParam),
100
101 // method invoked on a trait instance
102 MethodObject(MethodObject),
103
104 }
105
106 // details for a method invoked with a receiver whose type is a type parameter
107 // with a bounded trait.
108 #[deriving(Clone, Encodable, Decodable)]
109 pub struct MethodParam {
110 // the trait containing the method to be invoked
111 pub trait_id: ast::DefId,
112
113 // index of the method to be invoked amongst the trait's methods
114 pub method_num: uint,
115
116 // index of the type parameter (from those that are in scope) that is
117 // the type of the receiver
118 pub param_num: param_index,
119
120 // index of the bound for this type parameter which specifies the trait
121 pub bound_num: uint,
122 }
123
124 // details for a method invoked with a receiver whose type is an object
125 #[deriving(Clone, Encodable, Decodable)]
126 pub struct MethodObject {
127 // the (super)trait containing the method to be invoked
128 pub trait_id: ast::DefId,
129
130 // the actual base trait id of the object
131 pub object_trait_id: ast::DefId,
132
133 // index of the method to be invoked amongst the trait's methods
134 pub method_num: uint,
135
136 // index into the actual runtime vtable.
137 // the vtable is formed by concatenating together the method lists of
138 // the base object trait and all supertraits; this is the index into
139 // that vtable
140 pub real_index: uint,
141 }
142
143 #[deriving(Clone)]
144 pub struct MethodCallee {
145 pub origin: MethodOrigin,
146 pub ty: ty::t,
147 pub substs: ty::substs
148 }
149
150 #[deriving(Clone, Eq, TotalEq, Hash, Show)]
151 pub struct MethodCall {
152 pub expr_id: ast::NodeId,
153 pub autoderef: u32
154 }
155
156 impl MethodCall {
157 pub fn expr(id: ast::NodeId) -> MethodCall {
158 MethodCall {
159 expr_id: id,
160 autoderef: 0
161 }
162 }
163
164 pub fn autoderef(expr_id: ast::NodeId, autoderef: u32) -> MethodCall {
165 MethodCall {
166 expr_id: expr_id,
167 autoderef: 1 + autoderef
168 }
169 }
170 }
171
172 // maps from an expression id that corresponds to a method call to the details
173 // of the method to be invoked
174 pub type MethodMap = RefCell<FnvHashMap<MethodCall, MethodCallee>>;
175
176 pub type vtable_param_res = Vec<vtable_origin>;
177 // Resolutions for bounds of all parameters, left to right, for a given path.
178 pub type vtable_res = Vec<vtable_param_res>;
179
180 #[deriving(Clone)]
181 pub enum vtable_origin {
182 /*
183 Statically known vtable. def_id gives the class or impl item
184 from whence comes the vtable, and tys are the type substs.
185 vtable_res is the vtable itself
186 */
187 vtable_static(ast::DefId, Vec<ty::t>, vtable_res),
188
189 /*
190 Dynamic vtable, comes from a parameter that has a bound on it:
191 fn foo<T:quux,baz,bar>(a: T) -- a's vtable would have a
192 vtable_param origin
193
194 The first argument is the param index (identifying T in the example),
195 and the second is the bound number (identifying baz)
196 */
197 vtable_param(param_index, uint),
198 }
199
200 impl Repr for vtable_origin {
201 fn repr(&self, tcx: &ty::ctxt) -> ~str {
202 match *self {
203 vtable_static(def_id, ref tys, ref vtable_res) => {
204 format!("vtable_static({:?}:{}, {}, {})",
205 def_id,
206 ty::item_path_str(tcx, def_id),
207 tys.repr(tcx),
208 vtable_res.repr(tcx))
209 }
210
211 vtable_param(x, y) => {
212 format!("vtable_param({:?}, {:?})", x, y)
213 }
214 }
215 }
216 }
217
218 pub type vtable_map = RefCell<FnvHashMap<MethodCall, vtable_res>>;
219
220
221 // Information about the vtable resolutions for a trait impl.
222 // Mostly the information is important for implementing default
223 // methods.
224 #[deriving(Clone)]
225 pub struct impl_res {
226 // resolutions for any bounded params on the trait definition
227 pub trait_vtables: vtable_res,
228 // resolutions for the trait /itself/ (and for supertraits)
229 pub self_vtables: vtable_param_res
230 }
231
232 impl Repr for impl_res {
233 fn repr(&self, tcx: &ty::ctxt) -> ~str {
234 format!("impl_res \\{trait_vtables={}, self_vtables={}\\}",
235 self.trait_vtables.repr(tcx),
236 self.self_vtables.repr(tcx))
237 }
238 }
239
240 pub type impl_vtable_map = RefCell<DefIdMap<impl_res>>;
241
242 pub struct CrateCtxt<'a> {
243 // A mapping from method call sites to traits that have that method.
244 trait_map: resolve::TraitMap,
245 tcx: &'a ty::ctxt
246 }
247
248 // Functions that write types into the node type table
249 pub fn write_ty_to_tcx(tcx: &ty::ctxt, node_id: ast::NodeId, ty: ty::t) {
250 debug!("write_ty_to_tcx({}, {})", node_id, ppaux::ty_to_str(tcx, ty));
251 assert!(!ty::type_needs_infer(ty));
252 tcx.node_types.borrow_mut().insert(node_id as uint, ty);
253 }
254 pub fn write_substs_to_tcx(tcx: &ty::ctxt,
255 node_id: ast::NodeId,
256 substs: Vec<ty::t> ) {
257 if substs.len() > 0u {
258 debug!("write_substs_to_tcx({}, {:?})", node_id,
259 substs.iter().map(|t| ppaux::ty_to_str(tcx, *t)).collect::<Vec<~str>>());
260 assert!(substs.iter().all(|t| !ty::type_needs_infer(*t)));
261
262 tcx.node_type_substs.borrow_mut().insert(node_id, substs);
263 }
264 }
265 pub fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> ast::Def {
266 match tcx.def_map.borrow().find(&id) {
267 Some(&x) => x,
268 _ => {
269 tcx.sess.span_fatal(sp, "internal error looking up a definition")
270 }
271 }
272 }
273
274 pub fn lookup_def_ccx(ccx: &CrateCtxt, sp: Span, id: ast::NodeId)
275 -> ast::Def {
276 lookup_def_tcx(ccx.tcx, sp, id)
277 }
278
279 pub fn no_params(t: ty::t) -> ty::ty_param_bounds_and_ty {
280 ty::ty_param_bounds_and_ty {
281 generics: ty::Generics {type_param_defs: Rc::new(Vec::new()),
282 region_param_defs: Rc::new(Vec::new())},
283 ty: t
284 }
285 }
286
287 pub fn require_same_types(tcx: &ty::ctxt,
288 maybe_infcx: Option<&infer::InferCtxt>,
289 t1_is_expected: bool,
290 span: Span,
291 t1: ty::t,
292 t2: ty::t,
293 msg: || -> ~str)
294 -> bool {
295 let result = match maybe_infcx {
296 None => {
297 let infcx = infer::new_infer_ctxt(tcx);
298 infer::mk_eqty(&infcx, t1_is_expected, infer::Misc(span), t1, t2)
299 }
300 Some(infcx) => {
301 infer::mk_eqty(infcx, t1_is_expected, infer::Misc(span), t1, t2)
302 }
303 };
304
305 match result {
306 Ok(_) => true,
307 Err(ref terr) => {
308 tcx.sess.span_err(span, msg() + ": " +
309 ty::type_err_to_str(tcx, terr));
310 ty::note_and_explain_type_err(tcx, terr);
311 false
312 }
313 }
314 }
315
316 fn check_main_fn_ty(ccx: &CrateCtxt,
317 main_id: ast::NodeId,
318 main_span: Span) {
319 let tcx = ccx.tcx;
320 let main_t = ty::node_id_to_type(tcx, main_id);
321 match ty::get(main_t).sty {
322 ty::ty_bare_fn(..) => {
323 match tcx.map.find(main_id) {
324 Some(ast_map::NodeItem(it)) => {
325 match it.node {
326 ast::ItemFn(_, _, _, ref ps, _)
327 if ps.is_parameterized() => {
328 tcx.sess.span_err(
329 main_span,
330 "main function is not allowed to have type parameters");
331 return;
332 }
333 _ => ()
334 }
335 }
336 _ => ()
337 }
338 let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
339 fn_style: ast::NormalFn,
340 abi: abi::Rust,
341 sig: ty::FnSig {
342 binder_id: main_id,
343 inputs: Vec::new(),
344 output: ty::mk_nil(),
345 variadic: false
346 }
347 });
348
349 require_same_types(tcx, None, false, main_span, main_t, se_ty,
350 || format!("main function expects type: `{}`",
351 ppaux::ty_to_str(ccx.tcx, se_ty)));
352 }
353 _ => {
354 tcx.sess.span_bug(main_span,
355 format!("main has a non-function type: found `{}`",
356 ppaux::ty_to_str(tcx, main_t)));
357 }
358 }
359 }
360
361 fn check_start_fn_ty(ccx: &CrateCtxt,
362 start_id: ast::NodeId,
363 start_span: Span) {
364 let tcx = ccx.tcx;
365 let start_t = ty::node_id_to_type(tcx, start_id);
366 match ty::get(start_t).sty {
367 ty::ty_bare_fn(_) => {
368 match tcx.map.find(start_id) {
369 Some(ast_map::NodeItem(it)) => {
370 match it.node {
371 ast::ItemFn(_,_,_,ref ps,_)
372 if ps.is_parameterized() => {
373 tcx.sess.span_err(
374 start_span,
375 "start function is not allowed to have type parameters");
376 return;
377 }
378 _ => ()
379 }
380 }
381 _ => ()
382 }
383
384 let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
385 fn_style: ast::NormalFn,
386 abi: abi::Rust,
387 sig: ty::FnSig {
388 binder_id: start_id,
389 inputs: vec!(
390 ty::mk_int(),
391 ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8()))
392 ),
393 output: ty::mk_int(),
394 variadic: false
395 }
396 });
397
398 require_same_types(tcx, None, false, start_span, start_t, se_ty,
399 || format!("start function expects type: `{}`", ppaux::ty_to_str(ccx.tcx, se_ty)));
400
401 }
402 _ => {
403 tcx.sess.span_bug(start_span,
404 format!("start has a non-function type: found `{}`",
405 ppaux::ty_to_str(tcx, start_t)));
406 }
407 }
408 }
409
410 fn check_for_entry_fn(ccx: &CrateCtxt) {
411 let tcx = ccx.tcx;
412 match *tcx.sess.entry_fn.borrow() {
413 Some((id, sp)) => match tcx.sess.entry_type.get() {
414 Some(session::EntryMain) => check_main_fn_ty(ccx, id, sp),
415 Some(session::EntryStart) => check_start_fn_ty(ccx, id, sp),
416 Some(session::EntryNone) => {}
417 None => tcx.sess.bug("entry function without a type")
418 },
419 None => {}
420 }
421 }
422
423 pub fn check_crate(tcx: &ty::ctxt,
424 trait_map: resolve::TraitMap,
425 krate: &ast::Crate) {
426 let time_passes = tcx.sess.time_passes();
427 let ccx = CrateCtxt {
428 trait_map: trait_map,
429 tcx: tcx
430 };
431
432 time(time_passes, "type collecting", (), |_|
433 collect::collect_item_types(&ccx, krate));
434
435 // this ensures that later parts of type checking can assume that items
436 // have valid types and not error
437 tcx.sess.abort_if_errors();
438
439 time(time_passes, "variance inference", (), |_|
440 variance::infer_variance(tcx, krate));
441
442 time(time_passes, "coherence checking", (), |_|
443 coherence::check_coherence(&ccx, krate));
444
445 time(time_passes, "type checking", (), |_|
446 check::check_item_types(&ccx, krate));
447
448 check_for_entry_fn(&ccx);
449 tcx.sess.abort_if_errors();
450 }
librustc/middle/typeck/mod.rs:150:44-150:44 -struct- definition:
pub struct MethodCall {
pub expr_id: ast::NodeId,
pub autoderef: u32
references:- 42librustc/middle/mem_categorization.rs:
librustc/middle/astencode.rs:
librustc/middle/trans/expr.rs:
librustc/middle/typeck/mod.rs:
librustc/middle/typeck/check/mod.rs:
librustc/middle/typeck/check/vtable.rs:
librustc/middle/typeck/check/writeback.rs:
librustc/middle/typeck/check/regionck.rs:
librustc/middle/mem_categorization.rs:
librustc/middle/trans/expr.rs:
librustc/middle/trans/common.rs:
librustc/middle/trans/meth.rs:
librustc/middle/ty.rs:
librustc/middle/trans/common.rs:
librustc/middle/typeck/mod.rs:224:19-224:19 -struct- definition:
pub struct impl_res {
// resolutions for any bounded params on the trait definition
pub trait_vtables: vtable_res,
references:- 12223: // methods.
225: pub struct impl_res {
librustc/middle/typeck/check/vtable.rs:
778: let res = impl_res {
779: trait_vtables: vtbls,
librustc/middle/typeck/mod.rs:
223: // methods.
225: pub struct impl_res {
--
232: impl Repr for impl_res {
233: fn repr(&self, tcx: &ty::ctxt) -> ~str {
--
240: pub type impl_vtable_map = RefCell<DefIdMap<impl_res>>;
librustc/metadata/encoder.rs:
127: ecx: &EncodeContext,
128: vtables: &typeck::impl_res) {
129: ebml_w.start_tag(tag_item_impl_vtables);
librustc/metadata/decoder.rs:
440: id: ast::NodeId,
441: tcx: &ty::ctxt) -> typeck::impl_res
442: {
librustc/metadata/csearch.rs:
239: pub fn get_impl_vtables(tcx: &ty::ctxt,
240: def: ast::DefId) -> typeck::impl_res {
241: let cstore = &tcx.sess.cstore;
librustc/middle/ty.rs:
3867: did: ast::DefId)
3868: -> typeck::impl_res {
3869: lookup_locally_or_in_crate_store(
librustc/metadata/decoder.rs:
447: typeck::impl_res {
448: trait_vtables: decoder.read_vtable_res(tcx, cdata),
librustc/middle/typeck/mod.rs:125:41-125:41 -struct- definition:
pub struct MethodObject {
// the (super)trait containing the method to be invoked
pub trait_id: ast::DefId,
references:- 18124: // details for a method invoked with a receiver whose type is an object
126: pub struct MethodObject {
librustc/middle/typeck/check/method.rs:
541: method_ty: Rc::new(m),
542: origin: MethodObject(MethodObject {
543: trait_id: new_trait_ref.def_id,
librustc/middle/astencode.rs:
606: typeck::MethodObject(
607: typeck::MethodObject {
608: trait_id: mo.trait_id.tr(xcx),
librustc/middle/typeck/mod.rs:
124: // details for a method invoked with a receiver whose type is an object
126: pub struct MethodObject {
librustc/middle/typeck/check/method.rs:
1329: MethodParam(MethodParam { trait_id: trait_id, .. }) |
1330: MethodObject(MethodObject { trait_id: trait_id, .. }) => {
1331: bad = self.tcx().destructor_for_type.borrow()
librustc/middle/lint.rs:
1585: })
1586: | typeck::MethodObject(typeck::MethodObject {
1587: trait_id: trait_id,
librustc/middle/privacy.rs:
752: MethodParam(MethodParam { trait_id: trait_id, .. }) |
753: MethodObject(MethodObject { trait_id: trait_id, .. }) => {
754: self.report_error(self.ensure_public(span, trait_id, None,
librustc/util/ppaux.rs:
825: impl Repr for typeck::MethodObject {
826: fn repr(&self, tcx: &ctxt) -> ~str {
librustc/middle/ty.rs:
3020: method_num: n_mth, ..}) |
3021: typeck::MethodObject(typeck::MethodObject {
3022: trait_id: trt_id,
librustc/middle/dead.rs:
106: })
107: | typeck::MethodObject(typeck::MethodObject {
108: trait_id: trait_id,
librustc/middle/typeck/mod.rs:175:1-175:1 -NK_AS_STR_TODO- definition:
pub type vtable_param_res = Vec<vtable_origin>;
// Resolutions for bounds of all parameters, left to right, for a given path.
pub type vtable_res = Vec<vtable_param_res>;
references:- 16228: // resolutions for the trait /itself/ (and for supertraits)
229: pub self_vtables: vtable_param_res
230: }
librustc/middle/typeck/check/vtable.rs:
122: ty: ty::t,
123: is_early: bool) -> vtable_param_res {
124: let tcx = vcx.tcx();
librustc/middle/astencode.rs:
647: ebml_w: &mut Encoder,
648: param_tables: &typeck::vtable_param_res) {
649: ebml_w.emit_from_vec(param_tables.as_slice(), |ebml_w, vtable_origin| {
--
696: tcx: &ty::ctxt, cdata: &cstore::crate_metadata)
697: -> typeck::vtable_param_res;
698: fn read_vtable_origin(&mut self,
librustc/middle/trans/monomorphize.rs:
33: vtables: Option<typeck::vtable_res>,
34: self_vtables: Option<typeck::vtable_param_res>,
35: ref_id: Option<ast::NodeId>)
librustc/middle/trans/callee.rs:
225: param_vtables.extend(range(0, num_method_vtables).map(
226: |_| -> typeck::vtable_param_res {
227: Vec::new()
librustc/middle/trans/common.rs:
182: pub vtables: Option<typeck::vtable_res>,
183: pub self_vtables: Option<typeck::vtable_param_res>
184: }
--
772: ds: &[typeck::vtable_origin])
773: -> typeck::vtable_param_res {
774: ds.iter().map(|d| {
librustc/middle/trans/meth.rs:
433: self_ty: ty::t,
434: origins: typeck::vtable_param_res)
435: -> ValueRef {
librustc/middle/astencode.rs:
726: tcx: &ty::ctxt, cdata: &cstore::crate_metadata)
727: -> typeck::vtable_param_res {
728: self.read_to_vec(|this| Ok(this.read_vtable_origin(tcx, cdata)))
librustc/middle/typeck/mod.rs:143:19-143:19 -struct- definition:
pub struct MethodCallee {
pub origin: MethodOrigin,
pub ty: ty::t,
references:- 26144: pub struct MethodCallee {
librustc/middle/typeck/check/writeback.rs:
269: method.repr(self.tcx()));
270: let mut new_method = MethodCallee {
271: origin: method.origin,
librustc/middle/typeck/check/method.rs:
1056: // return something so we don't get errors for every mutability
1057: return Some(MethodCallee {
1058: origin: relevant_candidates.get(0).origin,
--
1248: MethodCallee {
1249: origin: candidate.origin,
librustc/middle/typeck/mod.rs:
173: // of the method to be invoked
174: pub type MethodMap = RefCell<FnvHashMap<MethodCall, MethodCallee>>;
librustc/middle/typeck/check/method.rs:
1123: fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
1124: -> MethodCallee {
1125: // This method performs two sets of substitutions, one after the other:
librustc/middle/astencode.rs:
570: impl<'a> read_method_callee_helper for reader::Decoder<'a> {
571: fn read_method_callee(&mut self, xcx: &ExtendedDecodeContext) -> (u32, MethodCallee) {
572: self.read_struct("MethodCallee", 4, |this| {
librustc/util/ppaux.rs:
790: impl Repr for typeck::MethodCallee {
791: fn repr(&self, tcx: &ctxt) -> ~str {
librustc/middle/astencode.rs:
575: }).unwrap();
576: Ok((autoderef, MethodCallee {
577: origin: this.read_struct_field("origin", 1, |this| {
librustc/middle/typeck/mod.rs:173:31-173:31 -NK_AS_STR_TODO- definition:
// of the method to be invoked
pub type MethodMap = RefCell<FnvHashMap<MethodCall, MethodCallee>>;
pub type vtable_param_res = Vec<vtable_origin>;
references:- 6librustc/middle/typeck/check/mod.rs:
165: adjustments: RefCell<NodeMap<ty::AutoAdjustment>>,
166: method_map: MethodMap,
167: vtable_map: vtable_map,
librustc/middle/privacy.rs:
35: type Context<'a> = (&'a MethodMap, &'a resolve::ExportMap2);
librustc/middle/cfg/construct.rs:
33: pub fn construct(tcx: &ty::ctxt,
34: method_map: typeck::MethodMap,
35: blk: &ast::Block) -> CFG {
librustc/middle/ty.rs:
351: pub method_map: typeck::MethodMap,
352: pub vtable_map: typeck::vtable_map,
librustc/middle/cfg/mod.rs:
57: pub fn new(tcx: &ty::ctxt,
58: method_map: typeck::MethodMap,
59: blk: &ast::Block) -> CFG {
librustc/middle/typeck/mod.rs:278:1-278:1 -fn- definition:
pub fn no_params(t: ty::t) -> ty::ty_param_bounds_and_ty {
ty::ty_param_bounds_and_ty {
generics: ty::Generics {type_param_defs: Rc::new(Vec::new()),
references:- 2librustc/middle/typeck/check/mod.rs:
3762: let typ = fcx.local_ty(sp, nid);
3763: return no_params(typ);
3764: }
librustc/middle/typeck/collect.rs:
905: let typ = ccx.to_ty(&ExplicitRscope, t);
906: let tpt = no_params(typ);
librustc/middle/typeck/mod.rs:248:55-248:55 -fn- definition:
// Functions that write types into the node type table
pub fn write_ty_to_tcx(tcx: &ty::ctxt, node_id: ast::NodeId, ty: ty::t) {
debug!("write_ty_to_tcx({}, {})", node_id, ppaux::ty_to_str(tcx, ty));
references:- 15librustc/middle/typeck/check/writeback.rs:
162: let var_ty = var_ty.resolve(self.fcx, ResolvingLocal(l.span));
163: write_ty_to_tcx(self.tcx(), l.id, var_ty);
164: visit::walk_local(self, l, ());
--
197: let n_ty = n_ty.resolve(self.fcx, reason);
198: write_ty_to_tcx(self.tcx(), id, n_ty);
199: debug!("Node {} has type {}", id, n_ty.repr(self.tcx()));
librustc/middle/typeck/collect.rs:
598: let tpt = ty_of_item(ccx, it);
599: write_ty_to_tcx(tcx, it.id, tpt.ty);
600: get_enum_variant_types(ccx,
--
680: let tpt = ty_of_item(ccx, it);
681: write_ty_to_tcx(tcx, it.id, tpt.ty);
682: },
--
809: let tpt = ty_of_foreign_item(ccx, i, abi);
810: write_ty_to_tcx(ccx.tcx, i.id, tpt.ty);
librustc/middle/typeck/mod.rs:180:19-180:19 -enum- definition:
pub enum vtable_origin {
/*
Statically known vtable. def_id gives the class or impl item
references:- 18181: pub enum vtable_origin {
--
200: impl Repr for vtable_origin {
201: fn repr(&self, tcx: &ty::ctxt) -> ~str {
librustc/middle/typeck/check/vtable.rs:
282: trait_ref: Rc<ty::TraitRef>)
283: -> Option<vtable_origin> {
284: let tcx = vcx.tcx();
--
311: is_early: bool)
312: -> Option<vtable_origin> {
313: let tcx = vcx.tcx();
librustc/middle/typeck/check/writeback.rs:
383: impl Resolve for vtable_origin {
384: fn resolve(&self, fcx: &FnCtxt, reason: ResolveReason) -> vtable_origin {
385: match *self {
librustc/middle/astencode.rs:
733: tcx: &ty::ctxt, cdata: &cstore::crate_metadata)
734: -> typeck::vtable_origin {
735: self.read_enum("vtable_origin", |this| {
librustc/middle/trans/monomorphize.rs:
330: pub fn make_vtable_id(ccx: &CrateContext,
331: origin: &typeck::vtable_origin)
332: -> MonoId {
librustc/middle/trans/common.rs:
784: param_substs: Option<¶m_substs>,
785: vt: &typeck::vtable_origin)
786: -> typeck::vtable_origin {
--
822: n_bound: uint)
823: -> typeck::vtable_origin {
824: debug!("find_vtable(n_param={:?}, n_bound={}, ps={})",
librustc/middle/trans/meth.rs:
245: n_method: uint,
246: vtbl: typeck::vtable_origin)
247: -> Callee<'a> {
librustc/middle/typeck/check/vtable.rs:
221: is_early: bool)
222: -> Option<vtable_origin> {
223: debug!("lookup_vtable(ty={}, trait_ref={})",
librustc/middle/typeck/mod.rs:93:41-93:41 -enum- definition:
pub enum MethodOrigin {
// fully statically resolved method
MethodStatic(ast::DefId),
references:- 1494: pub enum MethodOrigin {
librustc/middle/typeck/check/method.rs:
323: method_ty: Rc<ty::Method>,
324: origin: MethodOrigin,
325: }
--
1434: fn report_candidate(&self, idx: uint, origin: &MethodOrigin) {
1435: match *origin {
librustc/middle/astencode.rs:
593: impl tr for MethodOrigin {
594: fn tr(&self, xcx: &ExtendedDecodeContext) -> MethodOrigin {
595: match *self {
librustc/middle/privacy.rs:
743: // Checks that a method is in scope.
744: fn check_method(&mut self, span: Span, origin: MethodOrigin,
745: ident: ast::Ident) {
librustc/util/ppaux.rs:
799: impl Repr for typeck::MethodOrigin {
800: fn repr(&self, tcx: &ctxt) -> ~str {
librustc/middle/ty.rs:
3009: pub fn method_call_type_param_defs(tcx: &ctxt, origin: typeck::MethodOrigin)
3010: -> Rc<Vec<TypeParameterDef>> {
librustc/middle/typeck/mod.rs:
144: pub struct MethodCallee {
145: pub origin: MethodOrigin,
146: pub ty: ty::t,
librustc/middle/typeck/mod.rs:264:2-264:2 -fn- definition:
}
pub fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> ast::Def {
match tcx.def_map.borrow().find(&id) {
references:- 3275: -> ast::Def {
276: lookup_def_tcx(ccx.tcx, sp, id)
277: }
librustc/middle/typeck/collect.rs:
827: match lookup_def_tcx(ccx.tcx, ast_trait_ref.path.span, ast_trait_ref.ref_id) {
828: ast::DefTrait(trait_did) => {
librustc/middle/typeck/astconv.rs:
887: ast::TraitTyParamBound(ref b) => {
888: match lookup_def_tcx(tcx, b.path.span, b.ref_id) {
889: ast::DefTrait(trait_did) => {
librustc/middle/typeck/mod.rs:217:1-217:1 -NK_AS_STR_TODO- definition:
pub type vtable_map = RefCell<FnvHashMap<MethodCall, vtable_res>>;
// Information about the vtable resolutions for a trait impl.
// Mostly the information is important for implementing default
references:- 2librustc/middle/ty.rs:
351: pub method_map: typeck::MethodMap,
352: pub vtable_map: typeck::vtable_map,
librustc/middle/typeck/check/mod.rs:
166: method_map: MethodMap,
167: vtable_map: vtable_map,
168: upvar_borrow_map: RefCell<ty::UpvarBorrowMap>,
librustc/middle/typeck/mod.rs:108:41-108:41 -struct- definition:
pub struct MethodParam {
// the trait containing the method to be invoked
pub trait_id: ast::DefId,
references:- 19107: // with a bounded trait.
109: pub struct MethodParam {
librustc/middle/typeck/check/method.rs:
601: method_ty: m,
602: origin: MethodParam(MethodParam {
603: trait_id: trait_ref.def_id,
librustc/middle/typeck/mod.rs:
107: // with a bounded trait.
109: pub struct MethodParam {
librustc/middle/typeck/check/method.rs:
1328: // that self has been merged in? -sully
1329: MethodParam(MethodParam { trait_id: trait_id, .. }) |
1330: MethodObject(MethodObject { trait_id: trait_id, .. }) => {
librustc/middle/lint.rs:
1580: }
1581: typeck::MethodParam(typeck::MethodParam {
1582: trait_id: trait_id,
librustc/middle/privacy.rs:
751: // is whether the trait itself is accessible or not.
752: MethodParam(MethodParam { trait_id: trait_id, .. }) |
753: MethodObject(MethodObject { trait_id: trait_id, .. }) => {
librustc/middle/dead.rs:
101: }
102: typeck::MethodParam(typeck::MethodParam {
103: trait_id: trait_id,
librustc/util/ppaux.rs:
815: impl Repr for typeck::MethodParam {
816: fn repr(&self, tcx: &ctxt) -> ~str {
librustc/middle/trans/meth.rs:
105: }
106: typeck::MethodParam(typeck::MethodParam {
107: trait_id: trait_id,
librustc/middle/ty.rs:
3017: }
3018: typeck::MethodParam(typeck::MethodParam {
3019: trait_id: trt_id,
librustc/middle/astencode.rs:
598: typeck::MethodParam(
599: typeck::MethodParam {
600: trait_id: mp.trait_id.tr(xcx),
librustc/middle/typeck/mod.rs:286:1-286:1 -fn- definition:
pub fn require_same_types(tcx: &ty::ctxt,
maybe_infcx: Option<&infer::InferCtxt>,
t1_is_expected: bool,
references:- 4398: require_same_types(tcx, None, false, start_span, start_t, se_ty,
399: || format!("start function expects type: `{}`", ppaux::ty_to_str(ccx.tcx, se_ty)));
librustc/middle/typeck/check/mod.rs:
4401: } else {
4402: require_same_types(
4403: tcx, None, false, it.span, i_ty.ty, fty,
librustc/middle/typeck/check/_match.rs:
446: debug!("pat_range ending type: {:?}", e_ty);
447: if !require_same_types(
448: tcx, Some(fcx.infcx()), false, pat.span, b_ty, e_ty,
librustc/middle/typeck/mod.rs:
349: require_same_types(tcx, None, false, main_span, main_t, se_ty,
350: || format!("main function expects type: `{}`",
librustc/middle/typeck/mod.rs:87:50-87:50 -enum- definition:
pub enum param_index {
param_numbered(uint),
param_self
references:- 1888: pub enum param_index {
--
196: */
197: vtable_param(param_index, uint),
198: }
librustc/middle/typeck/check/vtable.rs:
280: bounds: &[Rc<ty::TraitRef>],
281: param: param_index,
282: trait_ref: Rc<ty::TraitRef>)
librustc/middle/typeck/check/method.rs:
586: restrict_to: Option<DefId>,
587: param: param_index) {
588: self.push_inherent_candidates_from_bounds_inner(bounds,
librustc/middle/trans/common.rs:
820: ps: ¶m_substs,
821: n_param: typeck::param_index,
822: n_bound: uint)
librustc/middle/typeck/mod.rs:
117: // the type of the receiver
118: pub param_num: param_index,
librustc/middle/typeck/mod.rs:241:1-241:1 -struct- definition:
pub struct CrateCtxt<'a> {
// A mapping from method call sites to traits that have that method.
trait_map: resolve::TraitMap,
references:- 60librustc/middle/typeck/check/mod.rs:
librustc/middle/typeck/collect.rs:
librustc/middle/typeck/coherence.rs:
librustc/middle/typeck/check/mod.rs:
librustc/middle/typeck/mod.rs:177:78-177:78 -NK_AS_STR_TODO- definition:
// Resolutions for bounds of all parameters, left to right, for a given path.
pub type vtable_res = Vec<vtable_param_res>;
pub enum vtable_origin {
references:- 24218: pub type vtable_map = RefCell<FnvHashMap<MethodCall, vtable_res>>;
--
226: // resolutions for any bounded params on the trait definition
227: pub trait_vtables: vtable_res,
228: // resolutions for the trait /itself/ (and for supertraits)
librustc/middle/typeck/check/vtable.rs:
83: substs: &ty::substs,
84: is_early: bool) -> vtable_res {
85: debug!("lookup_vtables(span={:?}, \
--
789: pub fn trans_resolve_method(tcx: &ty::ctxt, id: ast::NodeId,
790: substs: &ty::substs) -> Option<vtable_res> {
791: let generics = ty::lookup_item_type(tcx, ast_util::local_def(id)).generics;
librustc/middle/astencode.rs:
706: cdata: &cstore::crate_metadata)
707: -> (u32, typeck::vtable_res) {
708: self.read_struct("VtableWithKey", 2, |this| {
--
719: tcx: &ty::ctxt, cdata: &cstore::crate_metadata)
720: -> typeck::vtable_res {
721: self.read_to_vec(|this| Ok(this.read_vtable_param_res(tcx, cdata)))
librustc/middle/trans/monomorphize.rs:
32: real_substs: &ty::substs,
33: vtables: Option<typeck::vtable_res>,
34: self_vtables: Option<typeck::vtable_param_res>,
librustc/middle/trans/callee.rs:
244: type_params: Vec<ty::t>, // values for fn's ty params
245: vtables: Option<typeck::vtable_res>) // vtables for the call
246: -> ValueRef {
librustc/middle/trans/common.rs:
751: vts: &[typeck::vtable_param_res])
752: -> typeck::vtable_res {
753: resolve_vtables_under_param_substs(fcx.ccx.tcx(),
--
760: vts: &[typeck::vtable_param_res])
761: -> typeck::vtable_res {
762: vts.iter().map(|ds| {
librustc/middle/trans/meth.rs:
281: rcvr_origins: typeck::vtable_res)
282: -> (Vec<ty::t>, typeck::vtable_res) {
283: /*!
--
488: substs: Vec<ty::t>,
489: vtables: typeck::vtable_res)
490: -> Vec<ValueRef> {
librustc/middle/astencode.rs:
690: cdata: &cstore::crate_metadata)
691: -> (u32, typeck::vtable_res);
692: fn read_vtable_res(&mut self,