FnCtxt normalization stuff
This commit is contained in:
parent
fc710832ea
commit
52cd342696
15 changed files with 41 additions and 67 deletions
|
@ -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
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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),
|
||||
);
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(),
|
||||
_ => {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
param_env,
|
||||
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
|
||||
} 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).
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue