Skip to main content

Module check

Module check 

Source
Expand description

Β§typeck: check phase

Within the check phase of type check, we check each item 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.

By far the most complex case is checking the body of a function. This can be broken down into several distinct phases:

  • gather: creates type variables to represent the type of each local variable and pattern binding.

  • main: the main pass does the lion’s share of the work: it determines the types of all expressions, resolves methods, checks for most invalid conditions, and so forth. In some cases, where a type is unknown, it may create a type or region variable and use that as the type of an expression.

    In the process of checking, various constraints will be placed on these type variables through the subtyping relationships requested through the demand module. The infer module is in charge of resolving those constraints.

  • regionck: after main is complete, the regionck pass goes over all types looking for regions and making sure that they did not escape into places where they are not in scope. This may also influence the final assignments of the various region variables if there is some flexibility.

  • writeback: writes the final types within a function body, replacing type variables with their final inferred types. These final types are written into the tcx.node_types table, which should never contain any reference to a type variable.

Β§Intermediate types

While type checking a function, the intermediate types for the expressions, blocks, and so forth contained within the function are stored in fcx.node_types and fcx.node_args. These types may contain unresolved type variables. After type checking is complete, the functions in the writeback module are used to take the types from this table, resolve them, and then write them into their permanent home in the type context tcx.

This means that during inferencing you should use fcx.write_ty() and fcx.expr_ty() / fcx.node_ty() to write/obtain the types of nodes within the function.

The types of top-level items, which never contain unbound type variables, are stored directly into the tcx typeck_results.

N.B., a type variable is not the same thing as a type parameter. A type variable is an instance of a type parameter. That is, given a generic function fn foo<T>(t: T), while checking the function foo, the type ty_param(0) refers to the type T, which is treated in abstract. However, when foo() is called, T will be instantiated with a fresh type variable N. This variable will eventually be resolved to some concrete type (which might itself be a type parameter).

Re-exportsΒ§

use std::borrow::Cow; πŸ”’
use std::num::NonZero; πŸ”’
pub use check::check_abi;
use rustc_abi::VariantIdx; πŸ”’
use rustc_attr_ir::lang_items::LangItem; πŸ”’
use rustc_data_structures::fx::FxHashSet; πŸ”’
use rustc_data_structures::fx::FxIndexMap; πŸ”’
use rustc_errors::ErrorGuaranteed; πŸ”’
use rustc_errors::pluralize; πŸ”’
use rustc_errors::struct_span_code_err; πŸ”’
use rustc_hir::def_id::DefId; πŸ”’
use rustc_hir::def_id::LocalDefId; πŸ”’
use rustc_hir::intravisit::Visitor; πŸ”’
use rustc_index::bit_set::DenseBitSet; πŸ”’
use rustc_infer::infer; πŸ”’
use rustc_infer::infer::TyCtxtInferExt as _; πŸ”’
use rustc_infer::traits::ObligationCause; πŸ”’
use rustc_infer::traits::TraitErrors; πŸ”’
use rustc_middle::middle::stability::EvalResult; πŸ”’
use rustc_middle::query::Providers; πŸ”’
use rustc_middle::ty::error::ExpectedFound; πŸ”’
use rustc_middle::ty::error::TypeError; πŸ”’
use rustc_middle::ty::print::with_types_for_signature; πŸ”’
use rustc_middle::ty; πŸ”’
use rustc_middle::ty::GenericArgs; πŸ”’
use rustc_middle::ty::OutlivesClause; πŸ”’
use rustc_middle::ty::Region; πŸ”’
use rustc_middle::ty::Ty; πŸ”’
use rustc_middle::ty::TyCtxt; πŸ”’
use rustc_middle::ty::TypingMode; πŸ”’
use rustc_session::diagnostics::feature_err; πŸ”’
use rustc_span::def_id::CRATE_DEF_ID; πŸ”’
use rustc_span::BytePos; πŸ”’
use rustc_span::DUMMY_SP; πŸ”’
use rustc_span::Ident; πŸ”’
use rustc_span::Span; πŸ”’
use rustc_span::Symbol; πŸ”’
use rustc_span::bug; πŸ”’
use rustc_span::kw; πŸ”’
use rustc_span::span_bug; πŸ”’
use rustc_trait_selection::error_reporting::InferCtxtErrorExt; πŸ”’
use rustc_trait_selection::error_reporting::infer::ObligationCauseExt as _; πŸ”’
use rustc_trait_selection::error_reporting::traits::suggestions::ReturnsVisitor; πŸ”’
use rustc_trait_selection::traits::ObligationCtxt; πŸ”’
use tracing::debug; πŸ”’
use self::compare_impl_item::collect_return_position_impl_trait_in_trait_tys; πŸ”’
use self::region::region_scope_tree; πŸ”’
use crate::diagnostics::MissingTraitItemLabel; πŸ”’
use crate::diagnostics::MissingTraitItemSuggestion; πŸ”’
use crate::diagnostics::MissingTraitItemSuggestionNone; πŸ”’
use crate::diagnostics::MissingTraitItemSuggestionUnstable; πŸ”’
use crate::check_c_variadic_abi; πŸ”’
use crate::diagnostics; πŸ”’

ModulesΒ§

always_applicable
This module contains methods that assist in checking that impls are general enough, i.e. that they always apply to every valid instantaiton of the ADT they’re implemented for.
check πŸ”’
compare_eii πŸ”’
This module is very similar to compare_impl_item. Most logic is taken from there, since in a very similar way we’re comparing some declaration of a signature to an implementation. The major difference is that we don’t bother with self types, since for EIIs we’re comparing freestanding item.
compare_impl_item πŸ”’
entry πŸ”’
intrinsic
Type-checking for the #[rustc_intrinsic] intrinsics that the compiler exposes.
region πŸ”’
This file builds up the ScopeTree, which describes the parent links in the region hierarchy.
wfcheck

FunctionsΒ§

adt_async_destructor πŸ”’
adt_destructor πŸ”’
bad_variant_count πŸ”’
Emit an error when encountering two or more variants in a transparent enum.
bounds_from_generic_clauses πŸ”’
Re-sugar ty::GenericClauses in a way suitable to be used in structured suggestions.
check_function_signature
default_body_is_unstable πŸ”’
fn_sig_suggestion πŸ”’
Return placeholder code for the given function.
get_owner_return_paths πŸ”’
Given a DefId for an opaque type in return position, find its parent item’s return expressions.
impl_suggestion_span πŸ”’
maybe_check_static_with_link_section πŸ”’
missing_items_err πŸ”’
missing_items_must_implement_one_of_err πŸ”’
missing_items_suggestions πŸ”’
potentially_plural_count
provide πŸ”’
Adds query implementations to the Providers vtable, see rustc_middle::query
suggestion_signature πŸ”’
Return placeholder code for the given associated item. Similar to ty::AssocItem::suggestion, but appropriate for use as the code snippet of a structured suggestion.