mirror of
https://github.com/rust-lang/rust.git
synced 2025-09-27 04:31:18 +00:00
predefined opaques to method_autoderef_steps
This commit is contained in:
parent
1acd65cd6d
commit
b70a15f5f6
@ -13,7 +13,7 @@ use rustc_hir::def::DefKind;
|
||||
use rustc_hir_analysis::autoderef::{self, Autoderef};
|
||||
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
|
||||
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TyCtxtInferExt};
|
||||
use rustc_infer::traits::ObligationCauseCode;
|
||||
use rustc_infer::traits::{ObligationCauseCode, query};
|
||||
use rustc_middle::middle::stability;
|
||||
use rustc_middle::ty::elaborate::supertrait_def_ids;
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type};
|
||||
@ -30,7 +30,7 @@ use rustc_span::edit_distance::{
|
||||
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
|
||||
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
|
||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::query::CanonicalTyGoal;
|
||||
use rustc_trait_selection::traits::query::CanonicalMethodAutoderefStepsGoal;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::query::method_autoderef::{
|
||||
CandidateStep, MethodAutoderefBadTy, MethodAutoderefStepsResult,
|
||||
@ -389,10 +389,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
OP: FnOnce(ProbeContext<'_, 'tcx>) -> Result<R, MethodError<'tcx>>,
|
||||
{
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
let query_input = self.canonicalize_query(
|
||||
ParamEnvAnd { param_env: self.param_env, value: self_ty },
|
||||
&mut orig_values,
|
||||
);
|
||||
let predefined_opaques_in_body = if self.next_trait_solver() {
|
||||
self.tcx.mk_predefined_opaques_in_body_from_iter(
|
||||
self.inner.borrow_mut().opaque_types().iter_opaque_types().map(|(k, v)| (k, v.ty)),
|
||||
)
|
||||
} else {
|
||||
ty::List::empty()
|
||||
};
|
||||
let value = query::MethodAutoderefSteps { predefined_opaques_in_body, self_ty };
|
||||
let query_input = self
|
||||
.canonicalize_query(ParamEnvAnd { param_env: self.param_env, value }, &mut orig_values);
|
||||
|
||||
let steps = match mode {
|
||||
Mode::MethodCall => self.tcx.method_autoderef_steps(query_input),
|
||||
@ -403,8 +409,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// special handling for this "trivial case" is a good idea.
|
||||
|
||||
let infcx = &self.infcx;
|
||||
let (ParamEnvAnd { param_env: _, value: self_ty }, var_values) =
|
||||
let (ParamEnvAnd { param_env: _, value }, var_values) =
|
||||
infcx.instantiate_canonical(span, &query_input.canonical);
|
||||
let query::MethodAutoderefSteps { predefined_opaques_in_body: _, self_ty } = value;
|
||||
debug!(?self_ty, ?query_input, "probe_op: Mode::Path");
|
||||
MethodAutoderefStepsResult {
|
||||
steps: infcx.tcx.arena.alloc_from_iter([CandidateStep {
|
||||
@ -553,12 +560,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
pub(crate) fn method_autoderef_steps<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
goal: CanonicalTyGoal<'tcx>,
|
||||
goal: CanonicalMethodAutoderefStepsGoal<'tcx>,
|
||||
) -> MethodAutoderefStepsResult<'tcx> {
|
||||
debug!("method_autoderef_steps({:?})", goal);
|
||||
|
||||
let (ref infcx, goal, inference_vars) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &goal);
|
||||
let ParamEnvAnd { param_env, value: self_ty } = goal;
|
||||
let ParamEnvAnd {
|
||||
param_env,
|
||||
value: query::MethodAutoderefSteps { predefined_opaques_in_body, self_ty },
|
||||
} = goal;
|
||||
for (key, ty) in predefined_opaques_in_body {
|
||||
let prev =
|
||||
infcx.register_hidden_type_in_storage(key, ty::OpaqueHiddenType { span: DUMMY_SP, ty });
|
||||
// It may be possible that two entries in the opaque type storage end up
|
||||
// with the same key after resolving contained inference variables.
|
||||
//
|
||||
// We could put them in the duplicate list but don't have to. The opaques we
|
||||
// encounter here are already tracked in the caller, so there's no need to
|
||||
// also store them here. We'd take them out when computing the query response
|
||||
// and then discard them, as they're already present in the input.
|
||||
//
|
||||
// Ideally we'd drop duplicate opaque type definitions when computing
|
||||
// the canonical input. This is more annoying to implement and may cause a
|
||||
// perf regression, so we do it inside of the query for now.
|
||||
if let Some(prev) = prev {
|
||||
debug!(?key, ?ty, ?prev, "ignore duplicate in `opaque_types_storage`");
|
||||
}
|
||||
}
|
||||
|
||||
// If arbitrary self types is not enabled, we follow the chain of
|
||||
// `Deref<Target=T>`. If arbitrary self types is enabled, we instead
|
||||
@ -655,7 +683,8 @@ pub(crate) fn method_autoderef_steps<'tcx>(
|
||||
};
|
||||
|
||||
debug!("method_autoderef_steps: steps={:?} opt_bad_ty={:?}", steps, opt_bad_ty);
|
||||
|
||||
// Need to empty the opaque types storage before it gets dropped.
|
||||
let _ = infcx.take_opaque_types();
|
||||
MethodAutoderefStepsResult {
|
||||
steps: tcx.arena.alloc_from_iter(steps),
|
||||
opt_bad_ty: opt_bad_ty.map(|ty| &*tcx.arena.alloc(ty)),
|
||||
|
@ -124,7 +124,7 @@ use crate::query::plumbing::{
|
||||
};
|
||||
use crate::traits::query::{
|
||||
CanonicalAliasGoal, CanonicalDropckOutlivesGoal, CanonicalImpliedOutlivesBoundsGoal,
|
||||
CanonicalPredicateGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal,
|
||||
CanonicalMethodAutoderefStepsGoal, CanonicalPredicateGoal, CanonicalTypeOpAscribeUserTypeGoal,
|
||||
CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, DropckConstraint,
|
||||
DropckOutlivesResult, MethodAutoderefStepsResult, NoSolution, NormalizationResult,
|
||||
OutlivesBound,
|
||||
@ -2559,9 +2559,9 @@ rustc_queries! {
|
||||
}
|
||||
|
||||
query method_autoderef_steps(
|
||||
goal: CanonicalTyGoal<'tcx>
|
||||
goal: CanonicalMethodAutoderefStepsGoal<'tcx>
|
||||
) -> MethodAutoderefStepsResult<'tcx> {
|
||||
desc { "computing autoderef types for `{}`", goal.canonical.value.value }
|
||||
desc { "computing autoderef types for `{}`", goal.canonical.value.value.self_ty }
|
||||
}
|
||||
|
||||
/// Used by `-Znext-solver` to compute proof trees.
|
||||
|
@ -10,6 +10,7 @@ use rustc_span::Span;
|
||||
|
||||
use crate::error::DropCheckOverflow;
|
||||
use crate::infer::canonical::{Canonical, CanonicalQueryInput, QueryResponse};
|
||||
use crate::traits::solve;
|
||||
pub use crate::traits::solve::NoSolution;
|
||||
use crate::ty::{self, GenericArg, Ty, TyCtxt};
|
||||
|
||||
@ -67,7 +68,16 @@ pub mod type_op {
|
||||
pub type CanonicalAliasGoal<'tcx> =
|
||||
CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>;
|
||||
|
||||
pub type CanonicalTyGoal<'tcx> = CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>;
|
||||
pub type CanonicalMethodAutoderefStepsGoal<'tcx> =
|
||||
CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, MethodAutoderefSteps<'tcx>>>;
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
|
||||
pub struct MethodAutoderefSteps<'tcx> {
|
||||
/// The list of opaque types currently in the storage.
|
||||
///
|
||||
/// Only used by the new solver for now.
|
||||
pub predefined_opaques_in_body: solve::PredefinedOpaques<'tcx>,
|
||||
pub self_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
pub type CanonicalPredicateGoal<'tcx> =
|
||||
CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>;
|
||||
|
@ -74,7 +74,8 @@ use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
|
||||
use crate::thir::Thir;
|
||||
use crate::traits;
|
||||
use crate::traits::solve::{
|
||||
self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, QueryResult, inspect,
|
||||
self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, PredefinedOpaques,
|
||||
QueryResult, inspect,
|
||||
};
|
||||
use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
|
||||
use crate::ty::{
|
||||
@ -3127,6 +3128,14 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
|
||||
}
|
||||
|
||||
pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
|
||||
{
|
||||
T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
|
||||
}
|
||||
|
||||
pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user