1
Fork 0

FnCtxt normalization stuff

This commit is contained in:
Michael Goulet 2022-11-25 17:28:50 +00:00
parent fc710832ea
commit 52cd342696
15 changed files with 41 additions and 67 deletions

View file

@ -109,6 +109,9 @@ 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>;
/// Invoked when we encounter an error from some prior pass

View file

@ -53,6 +53,8 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
self.ocx.infcx.tcx
}
// Convenience function to normalize during wfcheck. This performs
// `ObligationCtxt::normalize`, but provides a nice `ObligationCauseCode`.
fn normalize<T>(&self, span: Span, loc: Option<WellFormedLoc>, value: T) -> T
where
T: TypeFoldable<'tcx>,

View file

@ -448,7 +448,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// previously appeared within a `Binder<>` and hence would not
// have been normalized before.
let fn_sig = self.replace_bound_vars_with_fresh_vars(call_expr.span, infer::FnCall, fn_sig);
let fn_sig = self.normalize_associated_types_in(call_expr.span, fn_sig);
let fn_sig = self.normalize(call_expr.span, fn_sig);
// Call the generic checker.
let expected_arg_tys = self.expected_inputs_for_expected_output(

View file

@ -752,7 +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_associated_types_in(
let f = fcx.normalize(
self.expr_span,
self.expr_ty.fn_sig(fcx.tcx),
);

View file

@ -214,7 +214,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if expected_sig.is_none()
&& let ty::PredicateKind::Clause(ty::Clause::Projection(proj_predicate)) = bound_predicate.skip_binder()
{
expected_sig = self.normalize_associated_types_in(
expected_sig = self.normalize(
obligation.cause.span,
self.deduce_sig_from_projection(
Some(obligation.cause.span),
@ -623,7 +623,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
// Astconv can't normalize inputs or outputs with escaping bound vars,
// so normalize them here, after we've wrapped them in a binder.
let result = self.normalize_associated_types_in(self.tcx.hir().span(hir_id), result);
let result = self.normalize(self.tcx.hir().span(hir_id), result);
let c_result = self.inh.infcx.canonicalize_response(result);
self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result);
@ -797,10 +797,8 @@ 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.inh.normalize_associated_types_in(
let liberated_sig = self.normalize(
body.value.span,
self.tcx.hir().local_def_id_to_hir_id(expr_def_id),
self.param_env,
liberated_sig,
);
ClosureSignatures { bound_sig, liberated_sig }

View file

@ -1141,8 +1141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return Err(TypeError::IntrinsicCast);
}
// The signature must match.
let a_sig = self.normalize_associated_types_in(new.span, a_sig);
let b_sig = self.normalize_associated_types_in(new.span, b_sig);
let (a_sig, b_sig) = self.normalize(new.span, (a_sig, b_sig));
let sig = self
.at(cause, self.param_env)
.trace(prev_ty, new_ty)

View file

@ -1664,7 +1664,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.fields
.iter()
.map(|f| {
let fru_ty = self.normalize_associated_types_in(
let fru_ty = self.normalize(
expr_span,
self.field_ty(base_expr.span, f, fresh_substs),
);
@ -1749,7 +1749,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.fields
.iter()
.map(|f| {
self.normalize_associated_types_in(expr_span, f.ty(self.tcx, substs))
self.normalize(expr_span, f.ty(self.tcx, substs))
})
.collect(),
_ => {

View file

@ -344,7 +344,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{
debug!("instantiate_type_scheme(value={:?}, substs={:?})", value, substs);
let value = EarlyBinder(value).subst(self.tcx, substs);
let result = self.normalize_associated_types_in(span, value);
let result = self.normalize(span, value);
debug!("instantiate_type_scheme = {:?}", result);
result
}
@ -360,7 +360,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let bounds = self.tcx.predicates_of(def_id);
let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
let result = bounds.instantiate(self.tcx, substs);
let result = self.normalize_associated_types_in(span, result);
let result = self.normalize(span, result);
debug!(
"instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
bounds, substs, result, spans,
@ -368,11 +368,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(result, spans)
}
pub(in super::super) fn normalize_associated_types_in<T>(&self, span: Span, value: T) -> T
pub(in super::super) fn normalize<T>(&self, span: Span, value: T) -> T
where
T: TypeFoldable<'tcx>,
{
self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
self.register_infer_ok_obligations(
self.at(&self.misc(span), self.param_env).normalize(value),
)
}
pub(in super::super) fn normalize_associated_types_in_as_infer_ok<T>(
@ -487,7 +489,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let span = self.tcx.def_span(anon_const.def_id);
let c = ty::Const::from_anon_const(self.tcx, anon_const.def_id);
self.register_wf_obligation(c.into(), span, ObligationCauseCode::WellFormed(None));
self.normalize_associated_types_in(span, c)
self.normalize(span, c)
}
}
}
@ -580,7 +582,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
field: &'tcx ty::FieldDef,
substs: SubstsRef<'tcx>,
) -> Ty<'tcx> {
self.normalize_associated_types_in(span, field.ty(self.tcx, substs))
self.normalize(span, field.ty(self.tcx, substs))
}
pub(in super::super) fn resolve_rvalue_scopes(&self, def_id: DefId) {
@ -1107,7 +1109,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Res::Local(hid) = res {
let ty = self.local_ty(span, hid).decl_ty;
let ty = self.normalize_associated_types_in(span, ty);
let ty = self.normalize(span, ty);
self.write_ty(hir_id, ty);
return (ty, res);
}

View file

@ -288,7 +288,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
if ty.has_escaping_bound_vars() {
ty // FIXME: normalization and escaping regions
} else {
self.normalize_associated_types_in(span, ty)
self.normalize(span, ty)
}
}

View file

@ -759,7 +759,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("suggest_missing_return_type: expected type {:?}", ty);
let bound_vars = self.tcx.late_bound_vars(fn_id);
let ty = Binder::bind_with_vars(ty, bound_vars);
let ty = self.normalize_associated_types_in(span, ty);
let ty = self.normalize(span, ty);
let ty = self.tcx.erase_late_bound_regions(ty);
if self.can_coerce(expected, ty) {
err.subdiagnostic(ExpectedReturnTypeLabel::Other { span, expected });
@ -920,7 +920,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, ty);
let bound_vars = self.tcx.late_bound_vars(fn_id);
let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars));
let ty = self.normalize_associated_types_in(expr.span, ty);
let ty = self.normalize(expr.span, ty);
let ty = match self.tcx.asyncness(fn_id.owner) {
hir::IsAsync::Async => {
let infcx = self.tcx.infer_ctxt().build();

View file

@ -235,7 +235,7 @@ pub fn resolve_interior<'a, 'tcx>(
counter += 1;
ty::BoundRegion { var, kind }
};
let ty = fcx.normalize_associated_types_in(cause.span, cause.ty);
let ty = fcx.normalize(cause.span, cause.ty);
let ty = fcx.tcx.fold_regions(ty, |region, current_depth| {
let br = match region.kind() {
ty::ReVar(vid) => {

View file

@ -7,13 +7,12 @@ use rustc_hir::def_id::LocalDefId;
use rustc_hir::HirIdMap;
use rustc_infer::infer;
use rustc_infer::infer::{DefiningAnchor, InferCtxt, InferOk, TyCtxtInferExt};
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::def_id::LocalDefIdMap;
use rustc_span::{self, Span};
use rustc_trait_selection::traits::{
self, NormalizeExt, ObligationCause, ObligationCtxt, TraitEngine, TraitEngineExt as _,
self, ObligationCause, ObligationCtxt, TraitEngine, TraitEngineExt as _,
};
use std::cell::RefCell;
@ -178,35 +177,4 @@ impl<'tcx> Inherited<'tcx> {
self.register_predicates(infer_ok.obligations);
infer_ok.value
}
pub(super) fn normalize_associated_types_in<T>(
&self,
span: Span,
body_id: hir::HirId,
param_env: ty::ParamEnv<'tcx>,
value: T,
) -> T
where
T: TypeFoldable<'tcx>,
{
self.normalize_associated_types_in_with_cause(
ObligationCause::misc(span, body_id),
param_env,
value,
)
}
pub(super) fn normalize_associated_types_in_with_cause<T>(
&self,
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
value: T,
) -> T
where
T: TypeFoldable<'tcx>,
{
let ok = self.at(&cause, param_env).normalize(value);
debug!(?ok);
self.register_infer_ok_obligations(ok)
}
}

View file

@ -48,6 +48,8 @@ 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;
@ -245,12 +247,13 @@ 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);
let fn_sig = inh.normalize_associated_types_in(
body.value.span,
body_id.hir_id,
// 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,
fn_sig,
);
)
.normalize(fn_sig));
check_fn(&inh, param_env, fn_sig, decl, def_id, body, None).0
} else {
let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
@ -304,7 +307,7 @@ fn typeck_with_fallback<'tcx>(
_ => fallback(),
});
let expected_type = fcx.normalize_associated_types_in(body.value.span, expected_type);
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).

View file

@ -106,7 +106,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// traits, no trait system method can be called before this point because they
// could alter our Self-type, except for normalizing the receiver from the
// signature (which is also done during probing).
let method_sig_rcvr = self.normalize_associated_types_in(self.span, method_sig.inputs()[0]);
let method_sig_rcvr = self.normalize(self.span, method_sig.inputs()[0]);
debug!(
"confirm: self_ty={:?} method_sig_rcvr={:?} method_sig={:?} method_predicates={:?}",
self_ty, method_sig_rcvr, method_sig, method_predicates
@ -114,7 +114,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
self.unify_receivers(self_ty, method_sig_rcvr, &pick, all_substs);
let (method_sig, method_predicates) =
self.normalize_associated_types_in(self.span, (method_sig, method_predicates));
self.normalize(self.span, (method_sig, method_predicates));
let method_sig = ty::Binder::dummy(method_sig);
// Make sure nobody calls `drop()` explicitly.

View file

@ -22,8 +22,7 @@ use rustc_span::symbol::Ident;
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
use rustc_target::abi::{Size, VariantIdx};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::NormalizeExt;
use rustc_trait_selection::traits::query::normalize::AtExt;
use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
use std::iter;
use crate::{match_def_path, path_res, paths};
@ -284,7 +283,7 @@ fn is_normalizable_helper<'tcx>(
cache.insert(ty, false);
let infcx = cx.tcx.infer_ctxt().build();
let cause = rustc_middle::traits::ObligationCause::dummy();
let result = if infcx.at(&cause, param_env).normalize(ty).is_ok() {
let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() {
match ty.kind() {
ty::Adt(def, substs) => def.variants().iter().all(|variant| {
variant