]> git.proxmox.com Git - rustc.git/blame - src/librustc_typeck/lib.rs
New upstream version 1.17.0+dfsg2
[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)]
8bb4bdeb 80#![cfg_attr(stage0,feature(field_init_shorthand))]
32a655c1 81#![feature(loop_break_value)]
85aaf69f 82#![feature(quote)]
1a4d82fc 83#![feature(rustc_diagnostic_macros)]
85aaf69f 84#![feature(rustc_private)]
85aaf69f 85#![feature(staged_api)]
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;
476ff2be 98extern crate rustc_data_structures;
3157f602 99extern crate rustc_errors as errors;
1a4d82fc 100
9cc50fc6 101pub use rustc::dep_graph;
54a0048b 102pub use rustc::hir;
1a4d82fc 103pub use rustc::lint;
1a4d82fc
JJ
104pub use rustc::middle;
105pub use rustc::session;
106pub use rustc::util;
107
7453a54e 108use dep_graph::DepNode;
54a0048b 109use hir::map as hir_map;
476ff2be 110use rustc::infer::InferOk;
54a0048b 111use rustc::ty::subst::Substs;
476ff2be 112use rustc::ty::{self, Ty, TyCtxt};
8bb4bdeb
XL
113use rustc::ty::maps::Providers;
114use rustc::traits::{ObligationCause, ObligationCauseCode, Reveal};
476ff2be 115use session::config;
1a4d82fc 116use util::common::time;
1a4d82fc 117
7453a54e
SL
118use syntax::ast;
119use syntax::abi::Abi;
3157f602 120use syntax_pos::Span;
1a4d82fc 121
476ff2be 122use std::iter;
85aaf69f
SL
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 129mod astconv;
62682a34 130pub mod collect;
85aaf69f 131mod constrained_type_params;
476ff2be 132mod impl_wf_check;
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
a7813a04 141fn require_c_abi_if_variadic(tcx: TyCtxt,
e9174d1e 142 decl: &hir::FnDecl,
7453a54e 143 abi: Abi,
c1a9b12d 144 span: Span) {
7453a54e 145 if decl.variadic && abi != Abi::C {
5bcae85e 146 let mut err = struct_span_err!(tcx.sess, span, E0045,
c1a9b12d 147 "variadic function must have C calling convention");
5bcae85e
SL
148 err.span_label(span, &("variadics require C calling conventions").to_string())
149 .emit();
c1a9b12d
SL
150 }
151}
152
8bb4bdeb 153fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
476ff2be 154 cause: &ObligationCause<'tcx>,
c30ab7b3
SL
155 expected: Ty<'tcx>,
156 actual: Ty<'tcx>)
a7813a04 157 -> bool {
8bb4bdeb 158 tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
476ff2be 159 match infcx.eq_types(false, &cause, expected, actual) {
c30ab7b3
SL
160 Ok(InferOk { obligations, .. }) => {
161 // FIXME(#32730) propagate obligations
162 assert!(obligations.is_empty());
163 true
164 }
165 Err(err) => {
32a655c1 166 infcx.report_mismatched_types(cause, expected, actual, err).emit();
c30ab7b3
SL
167 false
168 }
1a4d82fc 169 }
a7813a04 170 })
1a4d82fc
JJ
171}
172
8bb4bdeb
XL
173fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
174 main_id: ast::NodeId,
175 main_span: Span) {
32a655c1 176 let main_def_id = tcx.hir.local_def_id(main_id);
476ff2be 177 let main_t = tcx.item_type(main_def_id);
1a4d82fc 178 match main_t.sty {
54a0048b 179 ty::TyFnDef(..) => {
32a655c1 180 match tcx.hir.find(main_id) {
e9174d1e 181 Some(hir_map::NodeItem(it)) => {
1a4d82fc 182 match it.node {
9e0c209e
SL
183 hir::ItemFn(.., ref generics, _) => {
184 if generics.is_parameterized() {
8bb4bdeb 185 struct_span_err!(tcx.sess, generics.span, E0131,
5bcae85e 186 "main function is not allowed to have type parameters")
9e0c209e 187 .span_label(generics.span,
5bcae85e
SL
188 &format!("main cannot have type parameters"))
189 .emit();
190 return;
191 }
1a4d82fc
JJ
192 }
193 _ => ()
194 }
195 }
196 _ => ()
197 }
c30ab7b3 198 let substs = tcx.intern_substs(&[]);
a7813a04 199 let se_ty = tcx.mk_fn_def(main_def_id, substs,
8bb4bdeb
XL
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 );
1a4d82fc 208
5bcae85e 209 require_same_types(
8bb4bdeb 210 tcx,
476ff2be 211 &ObligationCause::new(main_span, main_id, ObligationCauseCode::MainFunctionType),
c30ab7b3
SL
212 se_ty,
213 main_t);
1a4d82fc
JJ
214 }
215 _ => {
54a0048b
SL
216 span_bug!(main_span,
217 "main has a non-function type: found `{}`",
218 main_t);
1a4d82fc
JJ
219 }
220 }
221}
222
8bb4bdeb
XL
223fn 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);
476ff2be 227 let start_t = tcx.item_type(start_def_id);
1a4d82fc 228 match start_t.sty {
54a0048b 229 ty::TyFnDef(..) => {
32a655c1 230 match tcx.hir.find(start_id) {
e9174d1e 231 Some(hir_map::NodeItem(it)) => {
1a4d82fc 232 match it.node {
9e0c209e 233 hir::ItemFn(..,ref ps,_)
1a4d82fc 234 if ps.is_parameterized() => {
9e0c209e 235 struct_span_err!(tcx.sess, ps.span, E0132,
5bcae85e 236 "start function is not allowed to have type parameters")
9e0c209e 237 .span_label(ps.span,
5bcae85e
SL
238 &format!("start function cannot have type parameters"))
239 .emit();
1a4d82fc
JJ
240 return;
241 }
242 _ => ()
243 }
244 }
245 _ => ()
246 }
247
c30ab7b3 248 let substs = tcx.intern_substs(&[]);
a7813a04 249 let se_ty = tcx.mk_fn_def(start_def_id, substs,
8bb4bdeb 250 ty::Binder(tcx.mk_fn_sig(
476ff2be 251 [
c34b1796 252 tcx.types.isize,
c1a9b12d 253 tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))
476ff2be
SL
254 ].iter().cloned(),
255 tcx.types.isize,
256 false,
8bb4bdeb
XL
257 hir::Unsafety::Normal,
258 Abi::Rust
259 ))
260 );
1a4d82fc 261
5bcae85e 262 require_same_types(
8bb4bdeb 263 tcx,
476ff2be 264 &ObligationCause::new(start_span, start_id, ObligationCauseCode::StartFunctionType),
c30ab7b3
SL
265 se_ty,
266 start_t);
1a4d82fc
JJ
267 }
268 _ => {
54a0048b
SL
269 span_bug!(start_span,
270 "start has a non-function type: found `{}`",
271 start_t);
1a4d82fc
JJ
272 }
273 }
274}
275
8bb4bdeb 276fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
7453a54e 277 let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn);
3157f602
XL
278 if let Some((id, sp)) = *tcx.sess.entry_fn.borrow() {
279 match tcx.sess.entry_type.get() {
8bb4bdeb
XL
280 Some(config::EntryMain) => check_main_fn_ty(tcx, id, sp),
281 Some(config::EntryStart) => check_start_fn_ty(tcx, id, sp),
1a4d82fc 282 Some(config::EntryNone) => {}
54a0048b 283 None => bug!("entry function without a type")
3157f602 284 }
1a4d82fc
JJ
285 }
286}
287
8bb4bdeb
XL
288pub fn provide(providers: &mut Providers) {
289 collect::provide(providers);
290 coherence::provide(providers);
291 check::provide(providers);
292}
293
5bcae85e 294pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
8bb4bdeb 295 -> Result<(), usize> {
1a4d82fc 296 let time_passes = tcx.sess.time_passes();
1a4d82fc 297
1a4d82fc
JJ
298 // this ensures that later parts of type checking can assume that items
299 // have valid types and not error
54a0048b 300 tcx.sess.track_errors(|| {
9cc50fc6 301 time(time_passes, "type collecting", ||
8bb4bdeb 302 collect::collect_item_types(tcx));
9cc50fc6 303
54a0048b 304 })?;
1a4d82fc 305
e9174d1e 306 time(time_passes, "variance inference", ||
1a4d82fc
JJ
307 variance::infer_variance(tcx));
308
476ff2be
SL
309 tcx.sess.track_errors(|| {
310 time(time_passes, "impl wf inference", ||
8bb4bdeb 311 impl_wf_check::impl_wf_check(tcx));
476ff2be
SL
312 })?;
313
54a0048b 314 tcx.sess.track_errors(|| {
9cc50fc6 315 time(time_passes, "coherence checking", ||
8bb4bdeb 316 coherence::check_coherence(tcx));
54a0048b 317 })?;
1a4d82fc 318
8bb4bdeb 319 time(time_passes, "wf checking", || check::check_wf_new(tcx))?;
1a4d82fc 320
8bb4bdeb 321 time(time_passes, "item-types checking", || check::check_item_types(tcx))?;
e9174d1e 322
8bb4bdeb 323 time(time_passes, "item-bodies checking", || check::check_item_bodies(tcx))?;
e9174d1e 324
a7813a04 325 check_unused::check_crate(tcx);
8bb4bdeb 326 check_for_entry_fn(tcx);
7453a54e
SL
327
328 let err_count = tcx.sess.err_count();
329 if err_count == 0 {
8bb4bdeb 330 Ok(())
7453a54e
SL
331 } else {
332 Err(err_count)
333 }
1a4d82fc 334}
d9579d0f 335
d9579d0f 336__build_diagnostic_array! { librustc_typeck, DIAGNOSTICS }