From 06786227fdb92f7a905cfd4a0131f2ec9db5072f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 25 Nov 2022 18:00:27 +0000 Subject: [PATCH] Simplify more FnCtxt normalization --- .../rustc_hir_analysis/src/astconv/mod.rs | 2 +- compiler/rustc_hir_typeck/src/cast.rs | 5 +-- compiler/rustc_hir_typeck/src/check.rs | 21 ++++------ compiler/rustc_hir_typeck/src/closure.rs | 12 ++---- compiler/rustc_hir_typeck/src/coercion.rs | 8 ++-- compiler/rustc_hir_typeck/src/expr.rs | 4 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 42 +------------------ .../src/fn_ctxt/suggestions.rs | 3 +- compiler/rustc_hir_typeck/src/lib.rs | 21 +++------- compiler/rustc_hir_typeck/src/method/mod.rs | 39 +++++++---------- 10 files changed, 46 insertions(+), 111 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 22ea83a13f0..82150310638 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -109,7 +109,7 @@ pub trait AstConv<'tcx> { ) -> Ty<'tcx>; /// Normalize an associated type coming from the user. - /// + /// /// This should only be used by astconv. Use `FnCtxt::normalize` /// or `ObligationCtxt::normalize` in downstream crates. fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>; diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 2a9679eed04..890a068a7be 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -752,10 +752,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { match *self.expr_ty.kind() { ty::FnDef(..) => { // Attempt a coercion to a fn pointer type. - let f = fcx.normalize( - self.expr_span, - self.expr_ty.fn_sig(fcx.tcx), - ); + let f = fcx.normalize(self.expr_span, self.expr_ty.fn_sig(fcx.tcx)); let res = fcx.try_coerce( self.expr, self.expr_ty, diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 1ceb07def72..0c9a350c295 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -1,6 +1,6 @@ use crate::coercion::CoerceMany; use crate::gather_locals::GatherLocalsVisitor; -use crate::{FnCtxt, Inherited}; +use crate::FnCtxt; use crate::{GeneratorTypes, UnsafetyState}; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -20,21 +20,16 @@ use std::cell::RefCell; /// /// * ... /// * inherited: other fields inherited from the enclosing fn (if any) -#[instrument(skip(inherited, body), level = "debug")] +#[instrument(skip(fcx, body), level = "debug")] pub(super) fn check_fn<'a, 'tcx>( - inherited: &'a Inherited<'tcx>, - param_env: ty::ParamEnv<'tcx>, + fcx: &mut FnCtxt<'a, 'tcx>, fn_sig: ty::FnSig<'tcx>, decl: &'tcx hir::FnDecl<'tcx>, fn_def_id: LocalDefId, body: &'tcx hir::Body<'tcx>, can_be_generator: Option, -) -> (FnCtxt<'a, 'tcx>, Option>) { - let fn_id = inherited.tcx.hir().local_def_id_to_hir_id(fn_def_id); - - // Create the function context. This is either derived from scratch or, - // in the case of closures, based on the outer context. - let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id); +) -> Option> { + let fn_id = fcx.tcx.hir().local_def_id_to_hir_id(fn_def_id); fcx.ps.set(UnsafetyState::function(fn_sig.unsafety, fn_id)); let tcx = fcx.tcx; @@ -47,7 +42,7 @@ pub(super) fn check_fn<'a, 'tcx>( declared_ret_ty, body.value.hir_id, decl.output.span(), - param_env, + fcx.param_env, )); fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty))); @@ -105,7 +100,7 @@ pub(super) fn check_fn<'a, 'tcx>( fcx.write_ty(param.hir_id, param_ty); } - inherited.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig); + fcx.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig); if let ty::Dynamic(_, _, ty::Dyn) = declared_ret_ty.kind() { // FIXME: We need to verify that the return type is `Sized` after the return expression has @@ -174,7 +169,7 @@ pub(super) fn check_fn<'a, 'tcx>( check_panic_info_fn(tcx, panic_impl_did.expect_local(), fn_sig, decl, declared_ret_ty); } - (fcx, gen_ty) + gen_ty } fn check_panic_info_fn( diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 33c87768ec1..5d3419b3b6e 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -79,16 +79,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?bound_sig, ?liberated_sig); + let mut fcx = FnCtxt::new(self, self.param_env.without_const(), body.value.hir_id); let generator_types = check_fn( - self, - self.param_env.without_const(), + &mut fcx, liberated_sig, closure.fn_decl, expr_def_id, body, closure.movability, - ) - .1; + ); let parent_substs = InternalSubsts::identity_for_item( self.tcx, @@ -797,10 +796,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> ClosureSignatures<'tcx> { let liberated_sig = self.tcx().liberate_late_bound_regions(expr_def_id.to_def_id(), bound_sig); - let liberated_sig = self.normalize( - body.value.span, - liberated_sig, - ); + let liberated_sig = self.normalize(body.value.span, liberated_sig); ClosureSignatures { bound_sig, liberated_sig } } } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index e93d95ee66d..f0b349f0c98 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -62,7 +62,9 @@ use rustc_span::{self, BytePos, DesugaringKind, Span}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, ObligationCtxt}; +use rustc_trait_selection::traits::{ + self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt, +}; use smallvec::{smallvec, SmallVec}; use std::ops::Deref; @@ -832,7 +834,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let b = self.shallow_resolve(b); let InferOk { value: b, mut obligations } = - self.normalize_associated_types_in_as_infer_ok(self.cause.span, b); + self.at(&self.cause, self.param_env).normalize(b); debug!("coerce_from_fn_item(a={:?}, b={:?})", a, b); match b.kind() { @@ -854,7 +856,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } let InferOk { value: a_sig, obligations: o1 } = - self.normalize_associated_types_in_as_infer_ok(self.cause.span, a_sig); + self.at(&self.cause, self.param_env).normalize(a_sig); obligations.extend(o1); let a_fn_pointer = self.tcx.mk_fn_ptr(a_sig); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 7b101fc5c66..0c5bbb3e20b 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1748,9 +1748,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Adt(adt, substs) if adt.is_struct() => variant .fields .iter() - .map(|f| { - self.normalize(expr_span, f.ty(self.tcx, substs)) - }) + .map(|f| self.normalize(expr_span, f.ty(self.tcx, substs))) .collect(), _ => { self.tcx diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 8ce9e40cfdb..952d2726259 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -16,7 +16,7 @@ use rustc_hir_analysis::astconv::{ }; use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; -use rustc_infer::infer::{InferOk, InferResult}; +use rustc_infer::infer::InferResult; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::TypeFoldable; @@ -31,9 +31,7 @@ use rustc_span::hygiene::DesugaringKind; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::{ - self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt, -}; +use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCauseCode, ObligationCtxt}; use std::collections::hash_map::Entry; use std::slice; @@ -377,42 +375,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } - pub(in super::super) fn normalize_associated_types_in_as_infer_ok( - &self, - span: Span, - value: T, - ) -> InferOk<'tcx, T> - where - T: TypeFoldable<'tcx>, - { - self.at(&ObligationCause::misc(span, self.body_id), self.param_env).normalize(value) - } - - pub(in super::super) fn normalize_op_associated_types_in_as_infer_ok( - &self, - span: Span, - value: T, - opt_input_expr: Option<&hir::Expr<'_>>, - ) -> InferOk<'tcx, T> - where - T: TypeFoldable<'tcx>, - { - self.at( - &ObligationCause::new( - span, - self.body_id, - traits::BinOp { - rhs_span: opt_input_expr.map(|expr| expr.span), - is_lit: opt_input_expr - .map_or(false, |expr| matches!(expr.kind, ExprKind::Lit(_))), - output_ty: None, - }, - ), - self.param_env, - ) - .normalize(value) - } - pub fn require_type_meets( &self, ty: Ty<'tcx>, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 10cc4e81819..b9a8d16311c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -20,6 +20,7 @@ use rustc_span::Span; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::DefIdOrName; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; +use rustc_trait_selection::traits::NormalizeExt; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn body_fn_sig(&self) -> Option> { @@ -245,7 +246,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // implied by wf, but also because that would possibly result in // erroneous errors later on. let infer::InferOk { value: output, obligations: _ } = - self.normalize_associated_types_in_as_infer_ok(expr.span, output); + self.at(&self.misc(expr.span), self.param_env).normalize(output); if output.is_ty_var() { None } else { Some((def_id_or_name, output, inputs)) } } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 11c56b5fce6..09bd123350d 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -48,8 +48,6 @@ pub use diverges::Diverges; pub use expectation::Expectation; pub use fn_ctxt::*; pub use inherited::{Inherited, InheritedBuilder}; -use rustc_infer::traits::ObligationCause; -use rustc_trait_selection::traits::NormalizeExt; use crate::check::check_fn; use crate::coercion::DynamicCoerceMany; @@ -235,9 +233,10 @@ fn typeck_with_fallback<'tcx>( let typeck_results = Inherited::build(tcx, def_id).enter(|inh| { let param_env = tcx.param_env(def_id); - let mut fcx = if let Some(hir::FnSig { header, decl, .. }) = fn_sig { + let mut fcx = FnCtxt::new(&inh, param_env, body.value.hir_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() { - let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id); >::ty_of_fn(&fcx, id, header.unsafety, header.abi, decl, None, None) } else { tcx.fn_sig(def_id) @@ -247,16 +246,10 @@ fn typeck_with_fallback<'tcx>( // 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); - // FIXME(compiler-errors): Remove - let fn_sig = inh - .register_infer_ok_obligations( - inh.at(&ObligationCause::misc(body.value.span, body_id.hir_id), - param_env, - ) - .normalize(fn_sig)); - check_fn(&inh, param_env, fn_sig, decl, def_id, body, None).0 + let fn_sig = fcx.normalize(body.value.span, fn_sig); + + check_fn(&mut fcx, fn_sig, decl, def_id, body, None); } else { - let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id); let expected_type = body_ty .and_then(|ty| match ty.kind { hir::TyKind::Infer => Some(>::ast_ty_to_ty(&fcx, ty)), @@ -316,8 +309,6 @@ fn typeck_with_fallback<'tcx>( fcx.check_expr_coercable_to_type(&body.value, expected_type, None); fcx.write_ty(id, expected_type); - - fcx }; fcx.type_inference_fallback(); diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 9c2de1763b0..ebbd5eb1e64 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -23,8 +23,8 @@ use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, Ty, TypeVisitable}; use rustc_span::symbol::Ident; use rustc_span::Span; -use rustc_trait_selection::traits; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; +use rustc_trait_selection::traits::{self, NormalizeExt}; use self::probe::{IsSuggestion, ProbeScope}; @@ -465,11 +465,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let fn_sig = fn_sig.subst(self.tcx, substs); let fn_sig = self.replace_bound_vars_with_fresh_vars(span, infer::FnCall, fn_sig); - let InferOk { value, obligations: o } = if is_op { - self.normalize_op_associated_types_in_as_infer_ok(span, fn_sig, opt_input_expr) + let cause = if is_op { + ObligationCause::new( + span, + self.body_id, + traits::BinOp { + rhs_span: opt_input_expr.map(|expr| expr.span), + is_lit: opt_input_expr + .map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))), + output_ty: None, + }, + ) } else { - self.normalize_associated_types_in_as_infer_ok(span, fn_sig) + traits::ObligationCause::misc(span, self.body_id) }; + + let InferOk { value, obligations: o } = self.at(&cause, self.param_env).normalize(fn_sig); let fn_sig = { obligations.extend(o); value @@ -485,11 +496,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // any late-bound regions appearing in its bounds. let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs); - let InferOk { value, obligations: o } = if is_op { - self.normalize_op_associated_types_in_as_infer_ok(span, bounds, opt_input_expr) - } else { - self.normalize_associated_types_in_as_infer_ok(span, bounds) - }; + let InferOk { value, obligations: o } = self.at(&cause, self.param_env).normalize(bounds); let bounds = { obligations.extend(o); value @@ -497,20 +504,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { assert!(!bounds.has_escaping_bound_vars()); - let cause = if is_op { - ObligationCause::new( - span, - self.body_id, - traits::BinOp { - rhs_span: opt_input_expr.map(|expr| expr.span), - is_lit: opt_input_expr - .map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))), - output_ty: None, - }, - ) - } else { - traits::ObligationCause::misc(span, self.body_id) - }; let predicates_cause = cause.clone(); obligations.extend(traits::predicates_for_generics( move |_, _| predicates_cause.clone(),