]> git.proxmox.com Git - rustc.git/blame - src/librustc_typeck/lib.rs
New upstream version 1.16.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
476ff2be 47 the `tcx.types` table for later use
1a4d82fc
JJ
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/")]
32a655c1 73#![deny(warnings)]
1a4d82fc 74
85aaf69f
SL
75#![allow(non_camel_case_types)]
76
77#![feature(box_patterns)]
1a4d82fc 78#![feature(box_syntax)]
9e0c209e 79#![feature(conservative_impl_trait)]
32a655c1 80#![feature(loop_break_value)]
85aaf69f 81#![feature(quote)]
1a4d82fc 82#![feature(rustc_diagnostic_macros)]
85aaf69f 83#![feature(rustc_private)]
85aaf69f 84#![feature(staged_api)]
1a4d82fc
JJ
85
86#[macro_use] extern crate log;
87#[macro_use] extern crate syntax;
3157f602 88extern crate syntax_pos;
1a4d82fc
JJ
89
90extern crate arena;
85aaf69f 91extern crate fmt_macros;
54a0048b 92#[macro_use] extern crate rustc;
e9174d1e 93extern crate rustc_platform_intrinsics as intrinsics;
b039eaaf 94extern crate rustc_back;
54a0048b
SL
95extern crate rustc_const_math;
96extern crate rustc_const_eval;
476ff2be 97extern crate rustc_data_structures;
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;
476ff2be 109use rustc::infer::InferOk;
54a0048b 110use rustc::ty::subst::Substs;
476ff2be
SL
111use rustc::ty::{self, Ty, TyCtxt};
112use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
113use session::config;
1a4d82fc 114use util::common::time;
1a4d82fc 115
7453a54e
SL
116use syntax::ast;
117use syntax::abi::Abi;
3157f602 118use syntax_pos::Span;
1a4d82fc 119
476ff2be 120use std::iter;
85aaf69f 121use std::cell::RefCell;
a7813a04 122use util::nodemap::NodeMap;
85aaf69f
SL
123
124// NB: This module needs to be declared first so diagnostics are
125// registered before they are used.
126pub mod diagnostics;
127
62682a34 128pub mod check;
a7813a04 129pub mod check_unused;
1a4d82fc 130mod astconv;
62682a34 131pub mod collect;
85aaf69f 132mod constrained_type_params;
476ff2be 133mod impl_wf_check;
62682a34
SL
134pub mod coherence;
135pub mod variance;
1a4d82fc 136
c34b1796 137pub struct TypeAndSubsts<'tcx> {
9e0c209e 138 pub substs: &'tcx Substs<'tcx>,
1a4d82fc
JJ
139 pub ty: Ty<'tcx>,
140}
141
c34b1796 142pub struct CrateCtxt<'a, 'tcx: 'a> {
a7813a04
XL
143 ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
144
85aaf69f
SL
145 /// A vector of every trait accessible in the whole crate
146 /// (i.e. including those from subcrates). This is used only for
147 /// error reporting, and so is lazily initialised and generally
148 /// shouldn't taint the common path (hence the RefCell).
62682a34 149 pub all_traits: RefCell<Option<check::method::AllTraitsVec>>,
a7813a04
XL
150
151 /// This stack is used to identify cycles in the user's source.
152 /// Note that these cycles can cross multiple items.
153 pub stack: RefCell<Vec<collect::AstConvRequest>>,
154
155 pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
5bcae85e
SL
156
157 /// Obligations which will have to be checked at the end of
158 /// type-checking, after all functions have been inferred.
159 /// The key is the NodeId of the item the obligations were from.
160 pub deferred_obligations: RefCell<NodeMap<Vec<traits::DeferredObligation<'tcx>>>>,
1a4d82fc
JJ
161}
162
a7813a04 163fn require_c_abi_if_variadic(tcx: TyCtxt,
e9174d1e 164 decl: &hir::FnDecl,
7453a54e 165 abi: Abi,
c1a9b12d 166 span: Span) {
7453a54e 167 if decl.variadic && abi != Abi::C {
5bcae85e 168 let mut err = struct_span_err!(tcx.sess, span, E0045,
c1a9b12d 169 "variadic function must have C calling convention");
5bcae85e
SL
170 err.span_label(span, &("variadics require C calling conventions").to_string())
171 .emit();
c1a9b12d
SL
172 }
173}
174
a7813a04 175fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
476ff2be 176 cause: &ObligationCause<'tcx>,
c30ab7b3
SL
177 expected: Ty<'tcx>,
178 actual: Ty<'tcx>)
a7813a04 179 -> bool {
32a655c1 180 ccx.tcx.infer_ctxt((), Reveal::NotSpecializable).enter(|infcx| {
476ff2be 181 match infcx.eq_types(false, &cause, expected, actual) {
c30ab7b3
SL
182 Ok(InferOk { obligations, .. }) => {
183 // FIXME(#32730) propagate obligations
184 assert!(obligations.is_empty());
185 true
186 }
187 Err(err) => {
32a655c1 188 infcx.report_mismatched_types(cause, expected, actual, err).emit();
c30ab7b3
SL
189 false
190 }
1a4d82fc 191 }
a7813a04 192 })
1a4d82fc
JJ
193}
194
195fn check_main_fn_ty(ccx: &CrateCtxt,
196 main_id: ast::NodeId,
197 main_span: Span) {
198 let tcx = ccx.tcx;
32a655c1 199 let main_def_id = tcx.hir.local_def_id(main_id);
476ff2be 200 let main_t = tcx.item_type(main_def_id);
1a4d82fc 201 match main_t.sty {
54a0048b 202 ty::TyFnDef(..) => {
32a655c1 203 match tcx.hir.find(main_id) {
e9174d1e 204 Some(hir_map::NodeItem(it)) => {
1a4d82fc 205 match it.node {
9e0c209e
SL
206 hir::ItemFn(.., ref generics, _) => {
207 if generics.is_parameterized() {
208 struct_span_err!(ccx.tcx.sess, generics.span, E0131,
5bcae85e 209 "main function is not allowed to have type parameters")
9e0c209e 210 .span_label(generics.span,
5bcae85e
SL
211 &format!("main cannot have type parameters"))
212 .emit();
213 return;
214 }
1a4d82fc
JJ
215 }
216 _ => ()
217 }
218 }
219 _ => ()
220 }
c30ab7b3 221 let substs = tcx.intern_substs(&[]);
a7813a04
XL
222 let se_ty = tcx.mk_fn_def(main_def_id, substs,
223 tcx.mk_bare_fn(ty::BareFnTy {
e9174d1e 224 unsafety: hir::Unsafety::Normal,
7453a54e 225 abi: Abi::Rust,
476ff2be 226 sig: ty::Binder(tcx.mk_fn_sig(iter::empty(), tcx.mk_nil(), false))
a7813a04 227 }));
1a4d82fc 228
5bcae85e
SL
229 require_same_types(
230 ccx,
476ff2be 231 &ObligationCause::new(main_span, main_id, ObligationCauseCode::MainFunctionType),
c30ab7b3
SL
232 se_ty,
233 main_t);
1a4d82fc
JJ
234 }
235 _ => {
54a0048b
SL
236 span_bug!(main_span,
237 "main has a non-function type: found `{}`",
238 main_t);
1a4d82fc
JJ
239 }
240 }
241}
242
243fn check_start_fn_ty(ccx: &CrateCtxt,
244 start_id: ast::NodeId,
245 start_span: Span) {
246 let tcx = ccx.tcx;
32a655c1 247 let start_def_id = ccx.tcx.hir.local_def_id(start_id);
476ff2be 248 let start_t = tcx.item_type(start_def_id);
1a4d82fc 249 match start_t.sty {
54a0048b 250 ty::TyFnDef(..) => {
32a655c1 251 match tcx.hir.find(start_id) {
e9174d1e 252 Some(hir_map::NodeItem(it)) => {
1a4d82fc 253 match it.node {
9e0c209e 254 hir::ItemFn(..,ref ps,_)
1a4d82fc 255 if ps.is_parameterized() => {
9e0c209e 256 struct_span_err!(tcx.sess, ps.span, E0132,
5bcae85e 257 "start function is not allowed to have type parameters")
9e0c209e 258 .span_label(ps.span,
5bcae85e
SL
259 &format!("start function cannot have type parameters"))
260 .emit();
1a4d82fc
JJ
261 return;
262 }
263 _ => ()
264 }
265 }
266 _ => ()
267 }
268
c30ab7b3 269 let substs = tcx.intern_substs(&[]);
a7813a04
XL
270 let se_ty = tcx.mk_fn_def(start_def_id, substs,
271 tcx.mk_bare_fn(ty::BareFnTy {
e9174d1e 272 unsafety: hir::Unsafety::Normal,
7453a54e 273 abi: Abi::Rust,
476ff2be
SL
274 sig: ty::Binder(tcx.mk_fn_sig(
275 [
c34b1796 276 tcx.types.isize,
c1a9b12d 277 tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))
476ff2be
SL
278 ].iter().cloned(),
279 tcx.types.isize,
280 false,
281 )),
a7813a04 282 }));
1a4d82fc 283
5bcae85e
SL
284 require_same_types(
285 ccx,
476ff2be 286 &ObligationCause::new(start_span, start_id, ObligationCauseCode::StartFunctionType),
c30ab7b3
SL
287 se_ty,
288 start_t);
1a4d82fc
JJ
289 }
290 _ => {
54a0048b
SL
291 span_bug!(start_span,
292 "start has a non-function type: found `{}`",
293 start_t);
1a4d82fc
JJ
294 }
295 }
296}
297
298fn check_for_entry_fn(ccx: &CrateCtxt) {
299 let tcx = ccx.tcx;
7453a54e 300 let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn);
3157f602
XL
301 if let Some((id, sp)) = *tcx.sess.entry_fn.borrow() {
302 match tcx.sess.entry_type.get() {
1a4d82fc
JJ
303 Some(config::EntryMain) => check_main_fn_ty(ccx, id, sp),
304 Some(config::EntryStart) => check_start_fn_ty(ccx, id, sp),
305 Some(config::EntryNone) => {}
54a0048b 306 None => bug!("entry function without a type")
3157f602 307 }
1a4d82fc
JJ
308 }
309}
310
5bcae85e 311pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
476ff2be 312 -> Result<NodeMap<Ty<'tcx>>, usize> {
1a4d82fc
JJ
313 let time_passes = tcx.sess.time_passes();
314 let ccx = CrateCtxt {
a7813a04 315 ast_ty_to_ty_cache: RefCell::new(NodeMap()),
85aaf69f 316 all_traits: RefCell::new(None),
a7813a04 317 stack: RefCell::new(Vec::new()),
5bcae85e
SL
318 tcx: tcx,
319 deferred_obligations: RefCell::new(NodeMap()),
1a4d82fc
JJ
320 };
321
1a4d82fc
JJ
322 // this ensures that later parts of type checking can assume that items
323 // have valid types and not error
54a0048b 324 tcx.sess.track_errors(|| {
9cc50fc6 325 time(time_passes, "type collecting", ||
a7813a04 326 collect::collect_item_types(&ccx));
9cc50fc6 327
54a0048b 328 })?;
1a4d82fc 329
e9174d1e 330 time(time_passes, "variance inference", ||
1a4d82fc
JJ
331 variance::infer_variance(tcx));
332
476ff2be
SL
333 tcx.sess.track_errors(|| {
334 time(time_passes, "impl wf inference", ||
335 impl_wf_check::impl_wf_check(&ccx));
336 })?;
337
54a0048b 338 tcx.sess.track_errors(|| {
9cc50fc6
SL
339 time(time_passes, "coherence checking", ||
340 coherence::check_coherence(&ccx));
54a0048b 341 })?;
1a4d82fc 342
54a0048b 343 time(time_passes, "wf checking", || check::check_wf_new(&ccx))?;
e9174d1e 344
54a0048b 345 time(time_passes, "item-types checking", || check::check_item_types(&ccx))?;
1a4d82fc 346
54a0048b 347 time(time_passes, "item-bodies checking", || check::check_item_bodies(&ccx))?;
e9174d1e 348
54a0048b 349 time(time_passes, "drop-impl checking", || check::check_drop_impls(&ccx))?;
e9174d1e 350
a7813a04 351 check_unused::check_crate(tcx);
1a4d82fc 352 check_for_entry_fn(&ccx);
7453a54e
SL
353
354 let err_count = tcx.sess.err_count();
355 if err_count == 0 {
476ff2be 356 Ok(ccx.ast_ty_to_ty_cache.into_inner())
7453a54e
SL
357 } else {
358 Err(err_count)
359 }
1a4d82fc 360}
d9579d0f 361
d9579d0f 362__build_diagnostic_array! { librustc_typeck, DIAGNOSTICS }