2014-11-26 12:11:29 +01:00
|
|
|
/*!
|
2012-11-29 01:20:41 +01:00
|
|
|
|
2019-02-08 14:53:55 +01:00
|
|
|
# typeck
|
2012-11-29 01:20:41 +01:00
|
|
|
|
|
|
|
The type checker is responsible for:
|
|
|
|
|
2018-11-27 03:59:49 +01:00
|
|
|
1. Determining the type of each expression.
|
|
|
|
2. Resolving methods and traits.
|
|
|
|
3. Guaranteeing that most type rules are met. ("Most?", you say, "why most?"
|
2012-11-29 01:20:41 +01:00
|
|
|
Well, dear reader, read on)
|
|
|
|
|
2018-11-27 03:59:49 +01:00
|
|
|
The main entry point is `check_crate()`. Type checking operates in
|
2013-10-29 11:08:34 +01:00
|
|
|
several major phases:
|
2012-11-29 01:20:41 +01:00
|
|
|
|
2013-10-29 11:08:34 +01:00
|
|
|
1. The collect phase first passes over all items and determines their
|
|
|
|
type, without examining their "innards".
|
|
|
|
|
2018-11-27 03:59:49 +01:00
|
|
|
2. Variance inference then runs to compute the variance of each parameter.
|
2013-10-29 11:08:34 +01:00
|
|
|
|
2018-11-27 03:59:49 +01:00
|
|
|
3. Coherence checks for overlapping or orphaned impls.
|
2013-10-29 11:08:34 +01:00
|
|
|
|
|
|
|
4. Finally, the check phase then checks function bodies and so forth.
|
|
|
|
Within the check phase, we check each function body one at a time
|
|
|
|
(bodies of function expressions are checked as part of the
|
|
|
|
containing function). Inference is used to supply types wherever
|
|
|
|
they are unknown. The actual checking of a function itself has
|
|
|
|
several phases (check, regionck, writeback), as discussed in the
|
|
|
|
documentation for the `check` module.
|
2012-11-29 01:20:41 +01:00
|
|
|
|
|
|
|
The type checker is defined into various submodules which are documented
|
|
|
|
independently:
|
|
|
|
|
|
|
|
- astconv: converts the AST representation of types
|
2018-11-27 03:59:49 +01:00
|
|
|
into the `ty` representation.
|
2012-11-29 01:20:41 +01:00
|
|
|
|
|
|
|
- collect: computes the types of each top-level item and enters them into
|
2018-11-27 03:59:49 +01:00
|
|
|
the `tcx.types` table for later use.
|
2012-11-29 01:20:41 +01:00
|
|
|
|
2018-11-27 03:59:49 +01:00
|
|
|
- coherence: enforces coherence rules, builds some tables.
|
2013-10-29 11:08:34 +01:00
|
|
|
|
|
|
|
- variance: variance inference
|
|
|
|
|
2017-09-28 02:18:41 +02:00
|
|
|
- outlives: outlives inference
|
|
|
|
|
2012-11-29 01:20:41 +01:00
|
|
|
- check: walks over function bodies and type checks them, inferring types for
|
|
|
|
local variables, type parameters, etc as necessary.
|
|
|
|
|
|
|
|
- infer: finds the types to use for each type variable such that
|
|
|
|
all subtyping and assignment constraints are met. In essence, the check
|
|
|
|
module specifies the constraints, and the infer module solves them.
|
|
|
|
|
2018-11-27 03:59:49 +01:00
|
|
|
## Note
|
2014-11-26 12:11:29 +01:00
|
|
|
|
|
|
|
This API is completely unstable and subject to change.
|
|
|
|
|
2012-11-29 01:20:41 +01:00
|
|
|
*/
|
2015-12-11 22:07:11 +01:00
|
|
|
|
2019-02-05 14:37:15 +01:00
|
|
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
|
2014-03-22 02:05:05 +01:00
|
|
|
#![allow(non_camel_case_types)]
|
2019-10-08 02:14:42 +02:00
|
|
|
#![feature(bool_to_option)]
|
2015-02-10 22:52:44 +01:00
|
|
|
#![feature(box_patterns)]
|
2015-01-30 21:26:44 +01:00
|
|
|
#![feature(box_syntax)]
|
2018-01-18 05:15:13 +01:00
|
|
|
#![feature(crate_visibility_modifier)]
|
2018-01-21 09:44:41 +01:00
|
|
|
#![feature(exhaustive_patterns)]
|
2019-06-11 21:03:44 +02:00
|
|
|
#![feature(in_band_lifetimes)]
|
2018-09-26 23:26:46 +02:00
|
|
|
#![feature(nll)]
|
2017-05-27 09:29:24 +02:00
|
|
|
#![feature(slice_patterns)]
|
2019-12-30 11:39:13 +01:00
|
|
|
#![feature(try_blocks)]
|
2019-12-11 15:55:29 +01:00
|
|
|
#![feature(never_type)]
|
2019-12-22 23:42:04 +01:00
|
|
|
#![recursion_limit = "256"]
|
2017-05-08 23:36:44 +02:00
|
|
|
|
2019-12-22 23:42:04 +01:00
|
|
|
#[macro_use]
|
|
|
|
extern crate log;
|
2018-09-15 19:23:30 +02:00
|
|
|
|
2019-12-22 23:42:04 +01:00
|
|
|
#[macro_use]
|
|
|
|
extern crate rustc;
|
2014-11-26 12:11:29 +01:00
|
|
|
|
2019-11-09 11:38:06 +01:00
|
|
|
// This is used by Clippy.
|
|
|
|
pub mod expr_use_visitor;
|
|
|
|
|
2018-01-23 03:07:35 +01:00
|
|
|
mod astconv;
|
2017-05-03 17:28:22 +02:00
|
|
|
mod check;
|
|
|
|
mod check_unused;
|
2018-01-23 03:07:35 +01:00
|
|
|
mod coherence;
|
2017-05-03 17:28:22 +02:00
|
|
|
mod collect;
|
2019-03-29 01:28:07 +01:00
|
|
|
mod constrained_generic_params;
|
2016-11-11 15:52:46 +01:00
|
|
|
mod impl_wf_check;
|
2019-11-09 11:38:06 +01:00
|
|
|
mod mem_categorization;
|
2018-01-23 03:07:35 +01:00
|
|
|
mod namespace;
|
2017-09-28 02:18:41 +02:00
|
|
|
mod outlives;
|
2019-12-22 23:42:04 +01:00
|
|
|
mod structured_errors;
|
2017-05-03 17:28:22 +02:00
|
|
|
mod variance;
|
2014-11-26 11:48:57 +01:00
|
|
|
|
2019-12-31 21:25:16 +01:00
|
|
|
use errors::struct_span_err;
|
2018-11-27 03:59:49 +01:00
|
|
|
use rustc::infer::InferOk;
|
|
|
|
use rustc::lint;
|
|
|
|
use rustc::middle;
|
|
|
|
use rustc::session;
|
2019-05-31 15:46:08 +02:00
|
|
|
use rustc::session::config::EntryFnType;
|
2018-11-27 03:59:49 +01:00
|
|
|
use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt};
|
2019-12-22 23:42:04 +01:00
|
|
|
use rustc::ty::query::Providers;
|
2019-02-09 15:11:53 +01:00
|
|
|
use rustc::ty::subst::SubstsRef;
|
2018-11-27 03:59:49 +01:00
|
|
|
use rustc::ty::{self, Ty, TyCtxt};
|
|
|
|
use rustc::util;
|
2019-12-22 23:42:04 +01:00
|
|
|
use rustc::util::common::ErrorReported;
|
2020-01-05 02:37:57 +01:00
|
|
|
use rustc_hir as hir;
|
|
|
|
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
|
|
|
use rustc_hir::Node;
|
2019-12-31 18:15:40 +01:00
|
|
|
use rustc_span::{Span, DUMMY_SP};
|
2019-12-22 23:42:04 +01:00
|
|
|
use rustc_target::spec::abi::Abi;
|
2018-11-27 03:59:49 +01:00
|
|
|
|
2019-11-11 22:46:56 +01:00
|
|
|
use rustc_error_codes::*;
|
|
|
|
|
2018-11-27 03:59:49 +01:00
|
|
|
use std::iter;
|
|
|
|
|
2019-03-16 01:04:02 +01:00
|
|
|
use astconv::{AstConv, Bounds};
|
2015-03-11 22:44:56 +01:00
|
|
|
pub struct TypeAndSubsts<'tcx> {
|
2019-02-09 15:11:53 +01:00
|
|
|
substs: SubstsRef<'tcx>,
|
2017-08-19 02:09:55 +02:00
|
|
|
ty: Ty<'tcx>,
|
2014-05-06 15:52:04 +02:00
|
|
|
}
|
|
|
|
|
2019-12-01 16:08:58 +01:00
|
|
|
fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
|
2019-02-08 18:30:42 +01:00
|
|
|
if decl.c_variadic && !(abi == Abi::C || abi == Abi::Cdecl) {
|
2019-12-22 23:42:04 +01:00
|
|
|
let mut err = struct_span_err!(
|
|
|
|
tcx.sess,
|
|
|
|
span,
|
|
|
|
E0045,
|
|
|
|
"C-variadic function must have C or cdecl calling convention"
|
|
|
|
);
|
2019-02-08 18:30:42 +01:00
|
|
|
err.span_label(span, "C-variadics require C or cdecl calling convention").emit();
|
2015-07-21 17:41:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-11 23:11:55 +02:00
|
|
|
fn require_same_types<'tcx>(
|
2019-06-13 23:48:52 +02:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2019-06-11 23:11:55 +02:00
|
|
|
cause: &ObligationCause<'tcx>,
|
|
|
|
expected: Ty<'tcx>,
|
|
|
|
actual: Ty<'tcx>,
|
|
|
|
) -> bool {
|
2017-06-09 09:55:16 +02:00
|
|
|
tcx.infer_ctxt().enter(|ref infcx| {
|
2018-02-10 19:18:02 +01:00
|
|
|
let param_env = ty::ParamEnv::empty();
|
2018-03-11 15:01:01 +01:00
|
|
|
let mut fulfill_cx = TraitEngine::new(infcx.tcx);
|
2017-05-24 15:43:20 +02:00
|
|
|
match infcx.at(&cause, param_env).eq(expected, actual) {
|
2016-10-04 01:19:40 +02:00
|
|
|
Ok(InferOk { obligations, .. }) => {
|
2017-04-18 21:48:32 +02:00
|
|
|
fulfill_cx.register_predicate_obligations(infcx, obligations);
|
2016-10-04 01:19:40 +02:00
|
|
|
}
|
|
|
|
Err(err) => {
|
2016-10-27 00:43:00 +02:00
|
|
|
infcx.report_mismatched_types(cause, expected, actual, err).emit();
|
2017-04-18 21:48:32 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
match fulfill_cx.select_all_or_error(infcx) {
|
|
|
|
Ok(()) => true,
|
|
|
|
Err(errors) => {
|
2018-03-12 05:15:06 +01:00
|
|
|
infcx.report_fulfillment_errors(&errors, None, false);
|
2016-10-04 01:19:40 +02:00
|
|
|
false
|
|
|
|
}
|
2012-11-29 01:20:41 +01:00
|
|
|
}
|
2016-05-02 17:07:47 +02:00
|
|
|
})
|
2012-11-29 01:20:41 +01:00
|
|
|
}
|
|
|
|
|
2019-06-21 23:49:03 +02:00
|
|
|
fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
2019-02-04 20:01:14 +01:00
|
|
|
let main_id = tcx.hir().as_local_hir_id(main_def_id).unwrap();
|
2019-01-13 13:06:26 +01:00
|
|
|
let main_span = tcx.def_span(main_def_id);
|
2017-04-24 14:20:46 +02:00
|
|
|
let main_t = tcx.type_of(main_def_id);
|
2019-09-16 20:08:35 +02:00
|
|
|
match main_t.kind {
|
2018-08-22 02:35:02 +02:00
|
|
|
ty::FnDef(..) => {
|
2019-06-24 09:58:49 +02:00
|
|
|
if let Some(Node::Item(it)) = tcx.hir().find(main_id) {
|
2019-09-26 18:51:36 +02:00
|
|
|
if let hir::ItemKind::Fn(.., ref generics, _) = it.kind {
|
2018-09-26 17:32:23 +02:00
|
|
|
let mut error = false;
|
|
|
|
if !generics.params.is_empty() {
|
|
|
|
let msg = "`main` function is not allowed to have generic \
|
2019-12-22 23:42:04 +01:00
|
|
|
parameters"
|
|
|
|
.to_owned();
|
2018-09-26 17:32:23 +02:00
|
|
|
let label = "`main` cannot have generic parameters".to_string();
|
|
|
|
struct_span_err!(tcx.sess, generics.span, E0131, "{}", msg)
|
|
|
|
.span_label(generics.span, label)
|
|
|
|
.emit();
|
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
if let Some(sp) = generics.where_clause.span() {
|
2019-12-22 23:42:04 +01:00
|
|
|
struct_span_err!(
|
|
|
|
tcx.sess,
|
|
|
|
sp,
|
|
|
|
E0646,
|
|
|
|
"`main` function is not allowed to have a `where` clause"
|
|
|
|
)
|
|
|
|
.span_label(sp, "`main` cannot have a `where` clause")
|
|
|
|
.emit();
|
2018-09-26 17:32:23 +02:00
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
if error {
|
|
|
|
return;
|
2012-11-29 01:20:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-12-21 13:07:50 +01:00
|
|
|
|
|
|
|
let actual = tcx.fn_sig(main_def_id);
|
2018-03-19 07:31:04 +01:00
|
|
|
let expected_return_type = if tcx.lang_items().termination().is_some() {
|
2017-12-21 14:20:03 +01:00
|
|
|
// we take the return type of the given main function, the real check is done
|
|
|
|
// in `check_fn`
|
|
|
|
actual.output().skip_binder()
|
|
|
|
} else {
|
|
|
|
// standard () main return type
|
2018-09-10 04:07:13 +02:00
|
|
|
tcx.mk_unit()
|
2017-12-21 14:20:03 +01:00
|
|
|
};
|
2017-12-21 13:07:50 +01:00
|
|
|
|
2019-12-22 23:42:04 +01:00
|
|
|
let se_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig(
|
|
|
|
iter::empty(),
|
|
|
|
expected_return_type,
|
|
|
|
false,
|
|
|
|
hir::Unsafety::Normal,
|
|
|
|
Abi::Rust,
|
|
|
|
)));
|
2017-12-21 13:07:50 +01:00
|
|
|
|
|
|
|
require_same_types(
|
|
|
|
tcx,
|
|
|
|
&ObligationCause::new(main_span, main_id, ObligationCauseCode::MainFunctionType),
|
|
|
|
se_ty,
|
2019-12-22 23:42:04 +01:00
|
|
|
tcx.mk_fn_ptr(actual),
|
|
|
|
);
|
2012-11-29 01:20:41 +01:00
|
|
|
}
|
|
|
|
_ => {
|
2019-12-22 23:42:04 +01:00
|
|
|
span_bug!(main_span, "main has a non-function type: found `{}`", main_t);
|
2012-11-29 01:20:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-21 23:49:03 +02:00
|
|
|
fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
2019-02-04 20:01:14 +01:00
|
|
|
let start_id = tcx.hir().as_local_hir_id(start_def_id).unwrap();
|
2019-01-13 13:06:26 +01:00
|
|
|
let start_span = tcx.def_span(start_def_id);
|
2017-04-24 14:20:46 +02:00
|
|
|
let start_t = tcx.type_of(start_def_id);
|
2019-09-16 20:08:35 +02:00
|
|
|
match start_t.kind {
|
2018-08-22 02:35:02 +02:00
|
|
|
ty::FnDef(..) => {
|
2019-06-24 09:58:49 +02:00
|
|
|
if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
|
2019-09-26 18:51:36 +02:00
|
|
|
if let hir::ItemKind::Fn(.., ref generics, _) = it.kind {
|
2018-09-26 17:32:23 +02:00
|
|
|
let mut error = false;
|
|
|
|
if !generics.params.is_empty() {
|
2019-12-22 23:42:04 +01:00
|
|
|
struct_span_err!(
|
|
|
|
tcx.sess,
|
|
|
|
generics.span,
|
|
|
|
E0132,
|
|
|
|
"start function is not allowed to have type parameters"
|
|
|
|
)
|
|
|
|
.span_label(generics.span, "start function cannot have type parameters")
|
|
|
|
.emit();
|
2018-09-26 17:32:23 +02:00
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
if let Some(sp) = generics.where_clause.span() {
|
2019-12-22 23:42:04 +01:00
|
|
|
struct_span_err!(
|
|
|
|
tcx.sess,
|
|
|
|
sp,
|
|
|
|
E0647,
|
|
|
|
"start function is not allowed to have a `where` clause"
|
|
|
|
)
|
|
|
|
.span_label(sp, "start function cannot have a `where` clause")
|
|
|
|
.emit();
|
2018-09-26 17:32:23 +02:00
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
if error {
|
|
|
|
return;
|
2013-04-09 10:16:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-22 23:42:04 +01:00
|
|
|
let se_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig(
|
|
|
|
[tcx.types.isize, tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))].iter().cloned(),
|
|
|
|
tcx.types.isize,
|
|
|
|
false,
|
|
|
|
hir::Unsafety::Normal,
|
|
|
|
Abi::Rust,
|
|
|
|
)));
|
2013-04-09 10:16:06 +02:00
|
|
|
|
2016-07-16 18:38:17 +02:00
|
|
|
require_same_types(
|
2016-10-04 01:19:40 +02:00
|
|
|
tcx,
|
2016-11-07 19:25:06 +01:00
|
|
|
&ObligationCause::new(start_span, start_id, ObligationCauseCode::StartFunctionType),
|
2016-08-30 05:44:21 +02:00
|
|
|
se_ty,
|
2019-12-22 23:42:04 +01:00
|
|
|
tcx.mk_fn_ptr(tcx.fn_sig(start_def_id)),
|
|
|
|
);
|
2013-04-09 10:16:06 +02:00
|
|
|
}
|
|
|
|
_ => {
|
2019-12-22 23:42:04 +01:00
|
|
|
span_bug!(start_span, "start has a non-function type: found `{}`", start_t);
|
2013-04-09 10:16:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-21 23:49:03 +02:00
|
|
|
fn check_for_entry_fn(tcx: TyCtxt<'_>) {
|
2019-01-13 13:06:26 +01:00
|
|
|
match tcx.entry_fn(LOCAL_CRATE) {
|
|
|
|
Some((def_id, EntryFnType::Main)) => check_main_fn_ty(tcx, def_id),
|
|
|
|
Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id),
|
|
|
|
_ => {}
|
2012-11-29 01:20:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 14:30:58 +01:00
|
|
|
pub fn provide(providers: &mut Providers<'_>) {
|
2017-02-14 00:11:24 +01:00
|
|
|
collect::provide(providers);
|
2017-02-19 13:46:29 +01:00
|
|
|
coherence::provide(providers);
|
2017-02-14 10:32:00 +01:00
|
|
|
check::provide(providers);
|
2017-04-24 17:15:12 +02:00
|
|
|
variance::provide(providers);
|
2017-09-28 03:01:48 +02:00
|
|
|
outlives::provide(providers);
|
2019-01-26 12:18:32 +01:00
|
|
|
impl_wf_check::provide(providers);
|
2017-02-14 00:11:24 +01:00
|
|
|
}
|
|
|
|
|
2019-06-21 23:49:03 +02:00
|
|
|
pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> {
|
2020-01-01 02:24:05 +01:00
|
|
|
let _prof_timer = tcx.sess.timer("type_check_crate");
|
2018-05-19 19:50:58 +02:00
|
|
|
|
2013-05-06 15:00:37 +02:00
|
|
|
// this ensures that later parts of type checking can assume that items
|
|
|
|
// have valid types and not error
|
2019-06-22 13:46:48 +02:00
|
|
|
// FIXME(matthewjasper) We shouldn't need to do this.
|
2016-03-23 04:01:37 +01:00
|
|
|
tcx.sess.track_errors(|| {
|
2020-01-01 02:24:05 +01:00
|
|
|
tcx.sess.time("type collecting", || {
|
2019-02-23 19:18:14 +01:00
|
|
|
for &module in tcx.hir().krate().modules.keys() {
|
2019-07-10 12:22:07 +02:00
|
|
|
tcx.ensure().collect_mod_item_types(tcx.hir().local_def_id(module));
|
2019-02-23 19:18:14 +01:00
|
|
|
}
|
|
|
|
});
|
2016-03-23 04:01:37 +01:00
|
|
|
})?;
|
2013-05-06 15:00:37 +02:00
|
|
|
|
2019-01-26 15:26:49 +01:00
|
|
|
if tcx.features().rustc_attrs {
|
|
|
|
tcx.sess.track_errors(|| {
|
2020-01-01 02:24:05 +01:00
|
|
|
tcx.sess.time("outlives testing", || outlives::test::test_inferred_outlives(tcx));
|
2019-01-26 15:26:49 +01:00
|
|
|
})?;
|
|
|
|
}
|
2017-09-28 03:20:44 +02:00
|
|
|
|
2016-11-11 15:52:46 +01:00
|
|
|
tcx.sess.track_errors(|| {
|
2020-01-01 02:24:05 +01:00
|
|
|
tcx.sess.time("impl wf inference", || impl_wf_check::impl_wf_check(tcx));
|
2016-11-11 15:52:46 +01:00
|
|
|
})?;
|
|
|
|
|
2016-03-23 04:01:37 +01:00
|
|
|
tcx.sess.track_errors(|| {
|
2020-01-01 02:24:05 +01:00
|
|
|
tcx.sess.time("coherence checking", || coherence::check_coherence(tcx));
|
2016-03-23 04:01:37 +01:00
|
|
|
})?;
|
2013-03-21 11:28:58 +01:00
|
|
|
|
2019-01-26 15:26:49 +01:00
|
|
|
if tcx.features().rustc_attrs {
|
|
|
|
tcx.sess.track_errors(|| {
|
2020-01-01 02:24:05 +01:00
|
|
|
tcx.sess.time("variance testing", || variance::test::test_variance(tcx));
|
2019-01-26 15:26:49 +01:00
|
|
|
})?;
|
|
|
|
}
|
2017-04-25 11:45:59 +02:00
|
|
|
|
2019-06-22 13:46:48 +02:00
|
|
|
tcx.sess.track_errors(|| {
|
2020-01-01 02:24:05 +01:00
|
|
|
tcx.sess.time("wf checking", || check::check_wf_new(tcx));
|
2019-06-22 13:46:48 +02:00
|
|
|
})?;
|
2015-08-07 15:39:54 +02:00
|
|
|
|
2020-01-01 02:24:05 +01:00
|
|
|
tcx.sess.time("item-types checking", || {
|
2019-04-20 00:37:34 +02:00
|
|
|
for &module in tcx.hir().krate().modules.keys() {
|
2019-07-10 12:22:07 +02:00
|
|
|
tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module));
|
2019-04-20 00:37:34 +02:00
|
|
|
}
|
|
|
|
});
|
2013-03-21 11:28:58 +01:00
|
|
|
|
2020-01-01 02:24:05 +01:00
|
|
|
tcx.sess.time("item-bodies checking", || tcx.typeck_item_bodies(LOCAL_CRATE));
|
2015-08-07 15:39:54 +02:00
|
|
|
|
2016-04-19 15:43:10 +02:00
|
|
|
check_unused::check_crate(tcx);
|
2016-10-04 01:19:40 +02:00
|
|
|
check_for_entry_fn(tcx);
|
2016-01-27 07:01:01 +01:00
|
|
|
|
2019-12-22 23:42:04 +01:00
|
|
|
if tcx.sess.err_count() == 0 { Ok(()) } else { Err(ErrorReported) }
|
2012-11-29 01:20:41 +01:00
|
|
|
}
|
2015-04-28 04:48:22 +02:00
|
|
|
|
2019-04-11 23:31:34 +02:00
|
|
|
/// A quasi-deprecated helper used in rustdoc and clippy to get
|
2017-05-03 17:28:22 +02:00
|
|
|
/// the type from a HIR node.
|
2019-12-01 16:08:58 +01:00
|
|
|
pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> {
|
2019-02-28 23:43:53 +01:00
|
|
|
// In case there are any projections, etc., find the "environment"
|
|
|
|
// def-ID that will be used to determine the traits/predicates in
|
2017-05-03 17:28:22 +02:00
|
|
|
// scope. This is derived from the enclosing item-like thing.
|
2019-02-18 10:59:17 +01:00
|
|
|
let env_node_id = tcx.hir().get_parent_item(hir_ty.hir_id);
|
2019-06-27 11:28:14 +02:00
|
|
|
let env_def_id = tcx.hir().local_def_id(env_node_id);
|
2017-05-03 17:28:22 +02:00
|
|
|
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id);
|
2018-09-26 17:32:23 +02:00
|
|
|
|
2017-11-18 16:49:37 +01:00
|
|
|
astconv::AstConv::ast_ty_to_ty(&item_cx, hir_ty)
|
|
|
|
}
|
|
|
|
|
2019-12-01 16:08:58 +01:00
|
|
|
pub fn hir_trait_to_predicates<'tcx>(
|
|
|
|
tcx: TyCtxt<'tcx>,
|
|
|
|
hir_trait: &hir::TraitRef<'_>,
|
|
|
|
) -> Bounds<'tcx> {
|
2019-02-28 23:43:53 +01:00
|
|
|
// In case there are any projections, etc., find the "environment"
|
|
|
|
// def-ID that will be used to determine the traits/predicates in
|
2017-11-18 16:49:37 +01:00
|
|
|
// scope. This is derived from the enclosing item-like thing.
|
2019-02-26 15:47:14 +01:00
|
|
|
let env_hir_id = tcx.hir().get_parent_item(hir_trait.hir_ref_id);
|
2019-06-27 11:28:14 +02:00
|
|
|
let env_def_id = tcx.hir().local_def_id(env_hir_id);
|
2017-11-18 16:49:37 +01:00
|
|
|
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id);
|
2019-03-16 01:04:02 +01:00
|
|
|
let mut bounds = Bounds::default();
|
2019-06-18 01:02:26 +02:00
|
|
|
let _ = AstConv::instantiate_poly_trait_ref_inner(
|
2019-12-22 23:42:04 +01:00
|
|
|
&item_cx,
|
|
|
|
hir_trait,
|
|
|
|
DUMMY_SP,
|
|
|
|
tcx.types.err,
|
|
|
|
&mut bounds,
|
|
|
|
true,
|
2017-11-18 16:49:37 +01:00
|
|
|
);
|
2018-09-26 17:32:23 +02:00
|
|
|
|
2019-06-18 01:02:26 +02:00
|
|
|
bounds
|
2017-05-03 17:28:22 +02:00
|
|
|
}
|