summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_typeck/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_typeck/src/lib.rs')
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs236
1 files changed, 116 insertions, 120 deletions
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index e397dfd45..45890abad 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -45,13 +45,14 @@ mod rvalue_scopes;
mod upvar;
mod writeback;
-pub use diverges::Diverges;
-pub use expectation::Expectation;
-pub use fn_ctxt::*;
-pub use inherited::{Inherited, InheritedBuilder};
+pub use fn_ctxt::FnCtxt;
+pub use inherited::Inherited;
use crate::check::check_fn;
use crate::coercion::DynamicCoerceMany;
+use crate::diverges::Diverges;
+use crate::expectation::Expectation;
+use crate::fn_ctxt::RawTy;
use crate::gather_locals::GatherLocalsVisitor;
use rustc_data_structures::unord::UnordSet;
use rustc_errors::{
@@ -74,7 +75,7 @@ use rustc_session::Session;
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::{sym, Span};
-fluent_messages! { "../locales/en-US.ftl" }
+fluent_messages! { "../messages.ftl" }
#[macro_export]
macro_rules! type_error_struct {
@@ -105,10 +106,9 @@ pub struct LocalTy<'tcx> {
/// (notably closures), `typeck_results(def_id)` would wind up
/// redirecting to the owning function.
fn primary_body_of(
- tcx: TyCtxt<'_>,
- id: hir::HirId,
+ node: Node<'_>,
) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnSig<'_>>)> {
- match tcx.hir().get(id) {
+ match node {
Node::Item(item) => match item.kind {
hir::ItemKind::Const(ty, body) | hir::ItemKind::Static(ty, _, body) => {
Some((body, Some(ty), None))
@@ -142,8 +142,7 @@ fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
}
if let Some(def_id) = def_id.as_local() {
- let id = tcx.hir().local_def_id_to_hir_id(def_id);
- primary_body_of(tcx, id).is_some()
+ primary_body_of(tcx.hir().get_by_def_id(def_id)).is_some()
} else {
false
}
@@ -198,143 +197,140 @@ fn typeck_with_fallback<'tcx>(
}
let id = tcx.hir().local_def_id_to_hir_id(def_id);
+ let node = tcx.hir().get(id);
let span = tcx.hir().span(id);
// Figure out what primary body this item has.
- let (body_id, body_ty, fn_sig) = primary_body_of(tcx, id).unwrap_or_else(|| {
+ let (body_id, body_ty, fn_sig) = primary_body_of(node).unwrap_or_else(|| {
span_bug!(span, "can't type-check body of {:?}", def_id);
});
let body = tcx.hir().body(body_id);
- let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
- let param_env = tcx.param_env(def_id);
- let param_env = if tcx.has_attr(def_id.to_def_id(), sym::rustc_do_not_const_check) {
- param_env.without_const()
+ let param_env = tcx.param_env(def_id);
+ let param_env = if tcx.has_attr(def_id, sym::rustc_do_not_const_check) {
+ param_env.without_const()
+ } else {
+ param_env
+ };
+ let inh = Inherited::new(tcx, def_id);
+ let mut fcx = FnCtxt::new(&inh, param_env, def_id);
+
+ if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
+ let fn_sig = if rustc_hir_analysis::collect::get_infer_ret_ty(&decl.output).is_some() {
+ fcx.astconv().ty_of_fn(id, header.unsafety, header.abi, decl, None, None)
} else {
- param_env
+ tcx.fn_sig(def_id).subst_identity()
};
- let mut fcx = FnCtxt::new(&inh, param_env, def_id);
-
- if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
- let fn_sig = if rustc_hir_analysis::collect::get_infer_ret_ty(&decl.output).is_some() {
- fcx.astconv().ty_of_fn(id, header.unsafety, header.abi, decl, None, None)
- } else {
- tcx.fn_sig(def_id).subst_identity()
- };
- check_abi(tcx, id, span, fn_sig.abi());
+ check_abi(tcx, id, span, fn_sig.abi());
- // Compute the function signature from point of view of inside the fn.
- let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
- let fn_sig = fcx.normalize(body.value.span, fn_sig);
+ // Compute the function signature from point of view of inside the fn.
+ let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
+ let fn_sig = fcx.normalize(body.value.span, fn_sig);
- check_fn(&mut fcx, fn_sig, decl, def_id, body, None);
- } else {
- let expected_type = body_ty
- .and_then(|ty| match ty.kind {
- hir::TyKind::Infer => Some(fcx.astconv().ast_ty_to_ty(ty)),
- _ => None,
- })
- .unwrap_or_else(|| match tcx.hir().get(id) {
- Node::AnonConst(_) => match tcx.hir().get(tcx.hir().parent_id(id)) {
- Node::Expr(&hir::Expr {
- kind: hir::ExprKind::ConstBlock(ref anon_const),
- ..
- }) if anon_const.hir_id == id => fcx.next_ty_var(TypeVariableOrigin {
- kind: TypeVariableOriginKind::TypeInference,
- span,
- }),
- Node::Ty(&hir::Ty {
- kind: hir::TyKind::Typeof(ref anon_const), ..
- }) if anon_const.hir_id == id => fcx.next_ty_var(TypeVariableOrigin {
- kind: TypeVariableOriginKind::TypeInference,
- span,
- }),
- Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
- | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => {
- let operand_ty =
- asm.operands.iter().find_map(|(op, _op_sp)| match op {
- hir::InlineAsmOperand::Const { anon_const }
- if anon_const.hir_id == id =>
- {
- // Inline assembly constants must be integers.
- Some(fcx.next_int_var())
- }
- hir::InlineAsmOperand::SymFn { anon_const }
- if anon_const.hir_id == id =>
- {
- Some(fcx.next_ty_var(TypeVariableOrigin {
- kind: TypeVariableOriginKind::MiscVariable,
- span,
- }))
- }
- _ => None,
- });
- operand_ty.unwrap_or_else(fallback)
+ check_fn(&mut fcx, fn_sig, decl, def_id, body, None);
+ } else {
+ let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty {
+ Some(fcx.next_ty_var(TypeVariableOrigin {
+ kind: TypeVariableOriginKind::TypeInference,
+ span,
+ }))
+ } else if let Node::AnonConst(_) = node {
+ match tcx.hir().get(tcx.hir().parent_id(id)) {
+ Node::Expr(&hir::Expr {
+ kind: hir::ExprKind::ConstBlock(ref anon_const), ..
+ }) if anon_const.hir_id == id => Some(fcx.next_ty_var(TypeVariableOrigin {
+ kind: TypeVariableOriginKind::TypeInference,
+ span,
+ })),
+ Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. })
+ if anon_const.hir_id == id =>
+ {
+ Some(fcx.next_ty_var(TypeVariableOrigin {
+ kind: TypeVariableOriginKind::TypeInference,
+ span,
+ }))
+ }
+ Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
+ | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => {
+ asm.operands.iter().find_map(|(op, _op_sp)| match op {
+ hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => {
+ // Inline assembly constants must be integers.
+ Some(fcx.next_int_var())
+ }
+ hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => {
+ Some(fcx.next_ty_var(TypeVariableOrigin {
+ kind: TypeVariableOriginKind::MiscVariable,
+ span,
+ }))
}
- _ => fallback(),
- },
- _ => fallback(),
- });
+ _ => None,
+ })
+ }
+ _ => None,
+ }
+ } else {
+ None
+ };
+ let expected_type = expected_type.unwrap_or_else(fallback);
- let expected_type = fcx.normalize(body.value.span, expected_type);
- fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
+ let expected_type = fcx.normalize(body.value.span, expected_type);
+ fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
- // Gather locals in statics (because of block expressions).
- GatherLocalsVisitor::new(&fcx).visit_body(body);
+ // Gather locals in statics (because of block expressions).
+ GatherLocalsVisitor::new(&fcx).visit_body(body);
- fcx.check_expr_coercable_to_type(&body.value, expected_type, None);
+ fcx.check_expr_coercible_to_type(&body.value, expected_type, None);
- fcx.write_ty(id, expected_type);
- };
+ fcx.write_ty(id, expected_type);
+ };
- fcx.type_inference_fallback();
-
- // Even though coercion casts provide type hints, we check casts after fallback for
- // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
- fcx.check_casts();
- fcx.select_obligations_where_possible(|_| {});
-
- // Closure and generator analysis may run after fallback
- // because they don't constrain other type variables.
- // Closure analysis only runs on closures. Therefore they only need to fulfill non-const predicates (as of now)
- let prev_constness = fcx.param_env.constness();
- fcx.param_env = fcx.param_env.without_const();
- fcx.closure_analyze(body);
- fcx.param_env = fcx.param_env.with_constness(prev_constness);
- assert!(fcx.deferred_call_resolutions.borrow().is_empty());
- // Before the generator analysis, temporary scopes shall be marked to provide more
- // precise information on types to be captured.
- fcx.resolve_rvalue_scopes(def_id.to_def_id());
-
- for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
- let ty = fcx.normalize(span, ty);
- fcx.require_type_is_sized(ty, span, code);
- }
+ fcx.type_inference_fallback();
+
+ // Even though coercion casts provide type hints, we check casts after fallback for
+ // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
+ fcx.check_casts();
+ fcx.select_obligations_where_possible(|_| {});
+
+ // Closure and generator analysis may run after fallback
+ // because they don't constrain other type variables.
+ // Closure analysis only runs on closures. Therefore they only need to fulfill non-const predicates (as of now)
+ let prev_constness = fcx.param_env.constness();
+ fcx.param_env = fcx.param_env.without_const();
+ fcx.closure_analyze(body);
+ fcx.param_env = fcx.param_env.with_constness(prev_constness);
+ assert!(fcx.deferred_call_resolutions.borrow().is_empty());
+ // Before the generator analysis, temporary scopes shall be marked to provide more
+ // precise information on types to be captured.
+ fcx.resolve_rvalue_scopes(def_id.to_def_id());
+
+ for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
+ let ty = fcx.normalize(span, ty);
+ fcx.require_type_is_sized(ty, span, code);
+ }
- fcx.select_obligations_where_possible(|_| {});
+ fcx.select_obligations_where_possible(|_| {});
- debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
+ debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
- // This must be the last thing before `report_ambiguity_errors`.
- fcx.resolve_generator_interiors(def_id.to_def_id());
+ // This must be the last thing before `report_ambiguity_errors`.
+ fcx.resolve_generator_interiors(def_id.to_def_id());
- debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
+ debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
- if let None = fcx.infcx.tainted_by_errors() {
- fcx.report_ambiguity_errors();
- }
+ if let None = fcx.infcx.tainted_by_errors() {
+ fcx.report_ambiguity_errors();
+ }
- if let None = fcx.infcx.tainted_by_errors() {
- fcx.check_transmutes();
- }
+ if let None = fcx.infcx.tainted_by_errors() {
+ fcx.check_transmutes();
+ }
- fcx.check_asms();
+ fcx.check_asms();
- fcx.infcx.skip_region_resolution();
+ fcx.infcx.skip_region_resolution();
- fcx.resolve_type_vars_in_body(body)
- });
+ let typeck_results = fcx.resolve_type_vars_in_body(body);
// Consistency check our TypeckResults instance can hold all ItemLocalIds
// it will need to hold.