]> git.proxmox.com Git - rustc.git/blob - src/librustc_typeck/lib.rs
New upstream version 1.17.0+dfsg1
[rustc.git] / src / librustc_typeck / lib.rs
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
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 `tcx.types` 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
62 This API is completely unstable and subject to change.
63
64 */
65
66 #![crate_name = "rustc_typeck"]
67 #![unstable(feature = "rustc_private", issue = "27812")]
68 #![crate_type = "dylib"]
69 #![crate_type = "rlib"]
70 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
71 html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
72 html_root_url = "https://doc.rust-lang.org/nightly/")]
73 #![deny(warnings)]
74
75 #![allow(non_camel_case_types)]
76
77 #![feature(box_patterns)]
78 #![feature(box_syntax)]
79 #![feature(conservative_impl_trait)]
80 #![cfg_attr(stage0,feature(field_init_shorthand))]
81 #![feature(loop_break_value)]
82 #![feature(quote)]
83 #![feature(rustc_diagnostic_macros)]
84 #![feature(rustc_private)]
85 #![feature(staged_api)]
86
87 #[macro_use] extern crate log;
88 #[macro_use] extern crate syntax;
89 extern crate syntax_pos;
90
91 extern crate arena;
92 extern crate fmt_macros;
93 #[macro_use] extern crate rustc;
94 extern crate rustc_platform_intrinsics as intrinsics;
95 extern crate rustc_back;
96 extern crate rustc_const_math;
97 extern crate rustc_const_eval;
98 extern crate rustc_data_structures;
99 extern crate rustc_errors as errors;
100
101 pub use rustc::dep_graph;
102 pub use rustc::hir;
103 pub use rustc::lint;
104 pub use rustc::middle;
105 pub use rustc::session;
106 pub use rustc::util;
107
108 use dep_graph::DepNode;
109 use hir::map as hir_map;
110 use rustc::infer::InferOk;
111 use rustc::ty::subst::Substs;
112 use rustc::ty::{self, Ty, TyCtxt};
113 use rustc::ty::maps::Providers;
114 use rustc::traits::{ObligationCause, ObligationCauseCode, Reveal};
115 use session::config;
116 use util::common::time;
117
118 use syntax::ast;
119 use syntax::abi::Abi;
120 use syntax_pos::Span;
121
122 use std::iter;
123 // NB: This module needs to be declared first so diagnostics are
124 // registered before they are used.
125 pub mod diagnostics;
126
127 pub mod check;
128 pub mod check_unused;
129 mod astconv;
130 pub mod collect;
131 mod constrained_type_params;
132 mod impl_wf_check;
133 pub mod coherence;
134 pub mod variance;
135
136 pub struct TypeAndSubsts<'tcx> {
137 pub substs: &'tcx Substs<'tcx>,
138 pub ty: Ty<'tcx>,
139 }
140
141 fn require_c_abi_if_variadic(tcx: TyCtxt,
142 decl: &hir::FnDecl,
143 abi: Abi,
144 span: Span) {
145 if decl.variadic && abi != Abi::C {
146 let mut err = struct_span_err!(tcx.sess, span, E0045,
147 "variadic function must have C calling convention");
148 err.span_label(span, &("variadics require C calling conventions").to_string())
149 .emit();
150 }
151 }
152
153 fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
154 cause: &ObligationCause<'tcx>,
155 expected: Ty<'tcx>,
156 actual: Ty<'tcx>)
157 -> bool {
158 tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
159 match infcx.eq_types(false, &cause, expected, actual) {
160 Ok(InferOk { obligations, .. }) => {
161 // FIXME(#32730) propagate obligations
162 assert!(obligations.is_empty());
163 true
164 }
165 Err(err) => {
166 infcx.report_mismatched_types(cause, expected, actual, err).emit();
167 false
168 }
169 }
170 })
171 }
172
173 fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
174 main_id: ast::NodeId,
175 main_span: Span) {
176 let main_def_id = tcx.hir.local_def_id(main_id);
177 let main_t = tcx.item_type(main_def_id);
178 match main_t.sty {
179 ty::TyFnDef(..) => {
180 match tcx.hir.find(main_id) {
181 Some(hir_map::NodeItem(it)) => {
182 match it.node {
183 hir::ItemFn(.., ref generics, _) => {
184 if generics.is_parameterized() {
185 struct_span_err!(tcx.sess, generics.span, E0131,
186 "main function is not allowed to have type parameters")
187 .span_label(generics.span,
188 &format!("main cannot have type parameters"))
189 .emit();
190 return;
191 }
192 }
193 _ => ()
194 }
195 }
196 _ => ()
197 }
198 let substs = tcx.intern_substs(&[]);
199 let se_ty = tcx.mk_fn_def(main_def_id, substs,
200 ty::Binder(tcx.mk_fn_sig(
201 iter::empty(),
202 tcx.mk_nil(),
203 false,
204 hir::Unsafety::Normal,
205 Abi::Rust
206 ))
207 );
208
209 require_same_types(
210 tcx,
211 &ObligationCause::new(main_span, main_id, ObligationCauseCode::MainFunctionType),
212 se_ty,
213 main_t);
214 }
215 _ => {
216 span_bug!(main_span,
217 "main has a non-function type: found `{}`",
218 main_t);
219 }
220 }
221 }
222
223 fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
224 start_id: ast::NodeId,
225 start_span: Span) {
226 let start_def_id = tcx.hir.local_def_id(start_id);
227 let start_t = tcx.item_type(start_def_id);
228 match start_t.sty {
229 ty::TyFnDef(..) => {
230 match tcx.hir.find(start_id) {
231 Some(hir_map::NodeItem(it)) => {
232 match it.node {
233 hir::ItemFn(..,ref ps,_)
234 if ps.is_parameterized() => {
235 struct_span_err!(tcx.sess, ps.span, E0132,
236 "start function is not allowed to have type parameters")
237 .span_label(ps.span,
238 &format!("start function cannot have type parameters"))
239 .emit();
240 return;
241 }
242 _ => ()
243 }
244 }
245 _ => ()
246 }
247
248 let substs = tcx.intern_substs(&[]);
249 let se_ty = tcx.mk_fn_def(start_def_id, substs,
250 ty::Binder(tcx.mk_fn_sig(
251 [
252 tcx.types.isize,
253 tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))
254 ].iter().cloned(),
255 tcx.types.isize,
256 false,
257 hir::Unsafety::Normal,
258 Abi::Rust
259 ))
260 );
261
262 require_same_types(
263 tcx,
264 &ObligationCause::new(start_span, start_id, ObligationCauseCode::StartFunctionType),
265 se_ty,
266 start_t);
267 }
268 _ => {
269 span_bug!(start_span,
270 "start has a non-function type: found `{}`",
271 start_t);
272 }
273 }
274 }
275
276 fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
277 let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn);
278 if let Some((id, sp)) = *tcx.sess.entry_fn.borrow() {
279 match tcx.sess.entry_type.get() {
280 Some(config::EntryMain) => check_main_fn_ty(tcx, id, sp),
281 Some(config::EntryStart) => check_start_fn_ty(tcx, id, sp),
282 Some(config::EntryNone) => {}
283 None => bug!("entry function without a type")
284 }
285 }
286 }
287
288 pub fn provide(providers: &mut Providers) {
289 collect::provide(providers);
290 coherence::provide(providers);
291 check::provide(providers);
292 }
293
294 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
295 -> Result<(), usize> {
296 let time_passes = tcx.sess.time_passes();
297
298 // this ensures that later parts of type checking can assume that items
299 // have valid types and not error
300 tcx.sess.track_errors(|| {
301 time(time_passes, "type collecting", ||
302 collect::collect_item_types(tcx));
303
304 })?;
305
306 time(time_passes, "variance inference", ||
307 variance::infer_variance(tcx));
308
309 tcx.sess.track_errors(|| {
310 time(time_passes, "impl wf inference", ||
311 impl_wf_check::impl_wf_check(tcx));
312 })?;
313
314 tcx.sess.track_errors(|| {
315 time(time_passes, "coherence checking", ||
316 coherence::check_coherence(tcx));
317 })?;
318
319 time(time_passes, "wf checking", || check::check_wf_new(tcx))?;
320
321 time(time_passes, "item-types checking", || check::check_item_types(tcx))?;
322
323 time(time_passes, "item-bodies checking", || check::check_item_bodies(tcx))?;
324
325 check_unused::check_crate(tcx);
326 check_for_entry_fn(tcx);
327
328 let err_count = tcx.sess.err_count();
329 if err_count == 0 {
330 Ok(())
331 } else {
332 Err(err_count)
333 }
334 }
335
336 __build_diagnostic_array! { librustc_typeck, DIAGNOSTICS }