]> git.proxmox.com Git - rustc.git/blame - src/librustc_typeck/lib.rs
New upstream version 1.13.0+dfsg1
[rustc.git] / src / librustc_typeck / lib.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 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
13typeck.rs, an introduction
14
15The type checker is responsible for:
16
171. Determining the type of each expression
182. Resolving methods and traits
193. Guaranteeing that most type rules are met ("most?", you say, "why most?"
20 Well, dear reader, read on)
21
22The main entry point is `check_crate()`. Type checking operates in
23several major phases:
24
251. The collect phase first passes over all items and determines their
26 type, without examining their "innards".
27
282. Variance inference then runs to compute the variance of each parameter
29
303. Coherence checks for overlapping or orphaned impls
31
324. 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
40The type checker is defined into various submodules which are documented
41independently:
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# Note
61
62This API is completely unstable and subject to change.
63
64*/
9cc50fc6 65
1a4d82fc 66#![crate_name = "rustc_typeck"]
e9174d1e 67#![unstable(feature = "rustc_private", issue = "27812")]
1a4d82fc
JJ
68#![crate_type = "dylib"]
69#![crate_type = "rlib"]
e9174d1e 70#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
62682a34 71 html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
e9174d1e 72 html_root_url = "https://doc.rust-lang.org/nightly/")]
7453a54e 73#![cfg_attr(not(stage0), deny(warnings))]
1a4d82fc 74
85aaf69f
SL
75#![allow(non_camel_case_types)]
76
77#![feature(box_patterns)]
1a4d82fc 78#![feature(box_syntax)]
9e0c209e
SL
79#![feature(conservative_impl_trait)]
80#![feature(dotdot_in_tuple_patterns)]
85aaf69f 81#![feature(quote)]
1a4d82fc 82#![feature(rustc_diagnostic_macros)]
85aaf69f 83#![feature(rustc_private)]
85aaf69f 84#![feature(staged_api)]
9e0c209e 85#![cfg_attr(stage0, feature(question_mark))]
1a4d82fc
JJ
86
87#[macro_use] extern crate log;
88#[macro_use] extern crate syntax;
3157f602 89extern crate syntax_pos;
1a4d82fc
JJ
90
91extern crate arena;
85aaf69f 92extern crate fmt_macros;
54a0048b 93#[macro_use] extern crate rustc;
e9174d1e 94extern crate rustc_platform_intrinsics as intrinsics;
b039eaaf 95extern crate rustc_back;
54a0048b
SL
96extern crate rustc_const_math;
97extern crate rustc_const_eval;
3157f602 98extern crate rustc_errors as errors;
1a4d82fc 99
9cc50fc6 100pub use rustc::dep_graph;
54a0048b 101pub use rustc::hir;
1a4d82fc 102pub use rustc::lint;
1a4d82fc
JJ
103pub use rustc::middle;
104pub use rustc::session;
105pub use rustc::util;
106
7453a54e 107use dep_graph::DepNode;
54a0048b 108use hir::map as hir_map;
a7813a04 109use rustc::infer::TypeOrigin;
54a0048b
SL
110use rustc::ty::subst::Substs;
111use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
5bcae85e 112use rustc::traits::{self, Reveal};
7453a54e 113use session::{config, CompileResult};
1a4d82fc 114use util::common::time;
1a4d82fc 115
7453a54e
SL
116use syntax::ast;
117use syntax::abi::Abi;
3157f602 118use syntax_pos::Span;
1a4d82fc 119
85aaf69f 120use std::cell::RefCell;
a7813a04 121use util::nodemap::NodeMap;
85aaf69f
SL
122
123// NB: This module needs to be declared first so diagnostics are
124// registered before they are used.
125pub mod diagnostics;
126
62682a34 127pub mod check;
a7813a04 128pub mod check_unused;
1a4d82fc
JJ
129mod rscope;
130mod astconv;
62682a34 131pub mod collect;
85aaf69f 132mod constrained_type_params;
62682a34
SL
133pub mod coherence;
134pub mod variance;
1a4d82fc 135
c34b1796 136pub struct TypeAndSubsts<'tcx> {
9e0c209e 137 pub substs: &'tcx Substs<'tcx>,
1a4d82fc
JJ
138 pub ty: Ty<'tcx>,
139}
140
c34b1796 141pub struct CrateCtxt<'a, 'tcx: 'a> {
a7813a04
XL
142 ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
143
85aaf69f
SL
144 /// A vector of every trait accessible in the whole crate
145 /// (i.e. including those from subcrates). This is used only for
146 /// error reporting, and so is lazily initialised and generally
147 /// shouldn't taint the common path (hence the RefCell).
62682a34 148 pub all_traits: RefCell<Option<check::method::AllTraitsVec>>,
a7813a04
XL
149
150 /// This stack is used to identify cycles in the user's source.
151 /// Note that these cycles can cross multiple items.
152 pub stack: RefCell<Vec<collect::AstConvRequest>>,
153
154 pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
5bcae85e
SL
155
156 /// Obligations which will have to be checked at the end of
157 /// type-checking, after all functions have been inferred.
158 /// The key is the NodeId of the item the obligations were from.
159 pub deferred_obligations: RefCell<NodeMap<Vec<traits::DeferredObligation<'tcx>>>>,
1a4d82fc
JJ
160}
161
162// Functions that write types into the node type table
a7813a04 163fn write_ty_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, node_id: ast::NodeId, ty: Ty<'tcx>) {
62682a34 164 debug!("write_ty_to_tcx({}, {:?})", node_id, ty);
c1a9b12d 165 assert!(!ty.needs_infer());
a7813a04 166 ccx.tcx.node_type_insert(node_id, ty);
1a4d82fc
JJ
167}
168
a7813a04 169fn write_substs_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
1a4d82fc
JJ
170 node_id: ast::NodeId,
171 item_substs: ty::ItemSubsts<'tcx>) {
172 if !item_substs.is_noop() {
62682a34 173 debug!("write_substs_to_tcx({}, {:?})",
1a4d82fc 174 node_id,
62682a34 175 item_substs);
1a4d82fc 176
9e0c209e 177 assert!(!item_substs.substs.needs_infer());
1a4d82fc 178
a7813a04 179 ccx.tcx.tables.borrow_mut().item_substs.insert(node_id, item_substs);
1a4d82fc
JJ
180 }
181}
c34b1796 182
a7813a04 183fn require_c_abi_if_variadic(tcx: TyCtxt,
e9174d1e 184 decl: &hir::FnDecl,
7453a54e 185 abi: Abi,
c1a9b12d 186 span: Span) {
7453a54e 187 if decl.variadic && abi != Abi::C {
5bcae85e 188 let mut err = struct_span_err!(tcx.sess, span, E0045,
c1a9b12d 189 "variadic function must have C calling convention");
5bcae85e
SL
190 err.span_label(span, &("variadics require C calling conventions").to_string())
191 .emit();
c1a9b12d
SL
192 }
193}
194
a7813a04 195fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
5bcae85e 196 origin: TypeOrigin,
a7813a04 197 t1: Ty<'tcx>,
5bcae85e 198 t2: Ty<'tcx>)
a7813a04 199 -> bool {
5bcae85e
SL
200 ccx.tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
201 if let Err(err) = infcx.eq_types(false, origin.clone(), t1, t2) {
202 infcx.report_mismatched_types(origin, t1, t2, err);
1a4d82fc 203 false
a7813a04
XL
204 } else {
205 true
1a4d82fc 206 }
a7813a04 207 })
1a4d82fc
JJ
208}
209
210fn check_main_fn_ty(ccx: &CrateCtxt,
211 main_id: ast::NodeId,
212 main_span: Span) {
213 let tcx = ccx.tcx;
c1a9b12d 214 let main_t = tcx.node_id_to_type(main_id);
1a4d82fc 215 match main_t.sty {
54a0048b 216 ty::TyFnDef(..) => {
1a4d82fc 217 match tcx.map.find(main_id) {
e9174d1e 218 Some(hir_map::NodeItem(it)) => {
1a4d82fc 219 match it.node {
9e0c209e
SL
220 hir::ItemFn(.., ref generics, _) => {
221 if generics.is_parameterized() {
222 struct_span_err!(ccx.tcx.sess, generics.span, E0131,
5bcae85e 223 "main function is not allowed to have type parameters")
9e0c209e 224 .span_label(generics.span,
5bcae85e
SL
225 &format!("main cannot have type parameters"))
226 .emit();
227 return;
228 }
1a4d82fc
JJ
229 }
230 _ => ()
231 }
232 }
233 _ => ()
234 }
b039eaaf 235 let main_def_id = tcx.map.local_def_id(main_id);
9e0c209e 236 let substs = Substs::empty(tcx);
a7813a04
XL
237 let se_ty = tcx.mk_fn_def(main_def_id, substs,
238 tcx.mk_bare_fn(ty::BareFnTy {
e9174d1e 239 unsafety: hir::Unsafety::Normal,
7453a54e 240 abi: Abi::Rust,
1a4d82fc
JJ
241 sig: ty::Binder(ty::FnSig {
242 inputs: Vec::new(),
5bcae85e 243 output: tcx.mk_nil(),
1a4d82fc
JJ
244 variadic: false
245 })
a7813a04 246 }));
1a4d82fc 247
5bcae85e
SL
248 require_same_types(
249 ccx,
250 TypeOrigin::MainFunctionType(main_span),
251 main_t,
252 se_ty);
1a4d82fc
JJ
253 }
254 _ => {
54a0048b
SL
255 span_bug!(main_span,
256 "main has a non-function type: found `{}`",
257 main_t);
1a4d82fc
JJ
258 }
259 }
260}
261
262fn check_start_fn_ty(ccx: &CrateCtxt,
263 start_id: ast::NodeId,
264 start_span: Span) {
265 let tcx = ccx.tcx;
c1a9b12d 266 let start_t = tcx.node_id_to_type(start_id);
1a4d82fc 267 match start_t.sty {
54a0048b 268 ty::TyFnDef(..) => {
1a4d82fc 269 match tcx.map.find(start_id) {
e9174d1e 270 Some(hir_map::NodeItem(it)) => {
1a4d82fc 271 match it.node {
9e0c209e 272 hir::ItemFn(..,ref ps,_)
1a4d82fc 273 if ps.is_parameterized() => {
9e0c209e 274 struct_span_err!(tcx.sess, ps.span, E0132,
5bcae85e 275 "start function is not allowed to have type parameters")
9e0c209e 276 .span_label(ps.span,
5bcae85e
SL
277 &format!("start function cannot have type parameters"))
278 .emit();
1a4d82fc
JJ
279 return;
280 }
281 _ => ()
282 }
283 }
284 _ => ()
285 }
286
54a0048b 287 let start_def_id = ccx.tcx.map.local_def_id(start_id);
9e0c209e 288 let substs = Substs::empty(tcx);
a7813a04
XL
289 let se_ty = tcx.mk_fn_def(start_def_id, substs,
290 tcx.mk_bare_fn(ty::BareFnTy {
e9174d1e 291 unsafety: hir::Unsafety::Normal,
7453a54e 292 abi: Abi::Rust,
1a4d82fc
JJ
293 sig: ty::Binder(ty::FnSig {
294 inputs: vec!(
c34b1796 295 tcx.types.isize,
c1a9b12d 296 tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))
1a4d82fc 297 ),
5bcae85e 298 output: tcx.types.isize,
1a4d82fc
JJ
299 variadic: false,
300 }),
a7813a04 301 }));
1a4d82fc 302
5bcae85e
SL
303 require_same_types(
304 ccx,
305 TypeOrigin::StartFunctionType(start_span),
306 start_t,
307 se_ty);
1a4d82fc
JJ
308 }
309 _ => {
54a0048b
SL
310 span_bug!(start_span,
311 "start has a non-function type: found `{}`",
312 start_t);
1a4d82fc
JJ
313 }
314 }
315}
316
317fn check_for_entry_fn(ccx: &CrateCtxt) {
318 let tcx = ccx.tcx;
7453a54e 319 let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn);
3157f602
XL
320 if let Some((id, sp)) = *tcx.sess.entry_fn.borrow() {
321 match tcx.sess.entry_type.get() {
1a4d82fc
JJ
322 Some(config::EntryMain) => check_main_fn_ty(ccx, id, sp),
323 Some(config::EntryStart) => check_start_fn_ty(ccx, id, sp),
324 Some(config::EntryNone) => {}
54a0048b 325 None => bug!("entry function without a type")
3157f602 326 }
1a4d82fc
JJ
327 }
328}
329
5bcae85e 330pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
a7813a04 331 -> CompileResult {
1a4d82fc
JJ
332 let time_passes = tcx.sess.time_passes();
333 let ccx = CrateCtxt {
a7813a04 334 ast_ty_to_ty_cache: RefCell::new(NodeMap()),
85aaf69f 335 all_traits: RefCell::new(None),
a7813a04 336 stack: RefCell::new(Vec::new()),
5bcae85e
SL
337 tcx: tcx,
338 deferred_obligations: RefCell::new(NodeMap()),
1a4d82fc
JJ
339 };
340
1a4d82fc
JJ
341 // this ensures that later parts of type checking can assume that items
342 // have valid types and not error
54a0048b 343 tcx.sess.track_errors(|| {
9cc50fc6 344 time(time_passes, "type collecting", ||
a7813a04 345 collect::collect_item_types(&ccx));
9cc50fc6 346
54a0048b 347 })?;
1a4d82fc 348
e9174d1e 349 time(time_passes, "variance inference", ||
1a4d82fc
JJ
350 variance::infer_variance(tcx));
351
54a0048b 352 tcx.sess.track_errors(|| {
9cc50fc6
SL
353 time(time_passes, "coherence checking", ||
354 coherence::check_coherence(&ccx));
54a0048b 355 })?;
1a4d82fc 356
54a0048b 357 time(time_passes, "wf checking", || check::check_wf_new(&ccx))?;
e9174d1e 358
54a0048b 359 time(time_passes, "item-types checking", || check::check_item_types(&ccx))?;
1a4d82fc 360
54a0048b 361 time(time_passes, "item-bodies checking", || check::check_item_bodies(&ccx))?;
e9174d1e 362
54a0048b 363 time(time_passes, "drop-impl checking", || check::check_drop_impls(&ccx))?;
e9174d1e 364
a7813a04 365 check_unused::check_crate(tcx);
1a4d82fc 366 check_for_entry_fn(&ccx);
7453a54e
SL
367
368 let err_count = tcx.sess.err_count();
369 if err_count == 0 {
370 Ok(())
371 } else {
372 Err(err_count)
373 }
1a4d82fc 374}
d9579d0f 375
d9579d0f 376__build_diagnostic_array! { librustc_typeck, DIAGNOSTICS }