Skip to content

Commit 478ba4b

Browse files
committed
predefined opaques to method_autoderef_steps
1 parent 36e21d3 commit 478ba4b

File tree

4 files changed

+63
-15
lines changed

4 files changed

+63
-15
lines changed

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_hir::def::DefKind;
1313
use rustc_hir_analysis::autoderef::{self, Autoderef};
1414
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
1515
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TyCtxtInferExt};
16-
use rustc_infer::traits::ObligationCauseCode;
16+
use rustc_infer::traits::{ObligationCauseCode, query};
1717
use rustc_middle::middle::stability;
1818
use rustc_middle::ty::elaborate::supertrait_def_ids;
1919
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type};
@@ -30,7 +30,7 @@ use rustc_span::edit_distance::{
3030
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
3131
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
3232
use rustc_trait_selection::infer::InferCtxtExt as _;
33-
use rustc_trait_selection::traits::query::CanonicalTyGoal;
33+
use rustc_trait_selection::traits::query::CanonicalMethodAutoderefStepsGoal;
3434
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
3535
use rustc_trait_selection::traits::query::method_autoderef::{
3636
CandidateStep, MethodAutoderefBadTy, MethodAutoderefStepsResult,
@@ -389,10 +389,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
389389
OP: FnOnce(ProbeContext<'_, 'tcx>) -> Result<R, MethodError<'tcx>>,
390390
{
391391
let mut orig_values = OriginalQueryValues::default();
392-
let query_input = self.canonicalize_query(
393-
ParamEnvAnd { param_env: self.param_env, value: self_ty },
394-
&mut orig_values,
395-
);
392+
let predefined_opaques_in_body = if self.next_trait_solver() {
393+
self.tcx.mk_predefined_opaques_in_body_from_iter(
394+
self.inner.borrow_mut().opaque_types().iter_opaque_types().map(|(k, v)| (k, v.ty)),
395+
)
396+
} else {
397+
ty::List::empty()
398+
};
399+
let value = query::MethodAutoderefSteps { predefined_opaques_in_body, self_ty };
400+
let query_input = self
401+
.canonicalize_query(ParamEnvAnd { param_env: self.param_env, value }, &mut orig_values);
396402

397403
let steps = match mode {
398404
Mode::MethodCall => self.tcx.method_autoderef_steps(query_input),
@@ -403,8 +409,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
403409
// special handling for this "trivial case" is a good idea.
404410

405411
let infcx = &self.infcx;
406-
let (ParamEnvAnd { param_env: _, value: self_ty }, var_values) =
412+
let (ParamEnvAnd { param_env: _, value }, var_values) =
407413
infcx.instantiate_canonical(span, &query_input.canonical);
414+
let query::MethodAutoderefSteps { predefined_opaques_in_body: _, self_ty } = value;
408415
debug!(?self_ty, ?query_input, "probe_op: Mode::Path");
409416
MethodAutoderefStepsResult {
410417
steps: infcx.tcx.arena.alloc_from_iter([CandidateStep {
@@ -553,12 +560,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
553560

554561
pub(crate) fn method_autoderef_steps<'tcx>(
555562
tcx: TyCtxt<'tcx>,
556-
goal: CanonicalTyGoal<'tcx>,
563+
goal: CanonicalMethodAutoderefStepsGoal<'tcx>,
557564
) -> MethodAutoderefStepsResult<'tcx> {
558565
debug!("method_autoderef_steps({:?})", goal);
559566

560567
let (ref infcx, goal, inference_vars) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &goal);
561-
let ParamEnvAnd { param_env, value: self_ty } = goal;
568+
let ParamEnvAnd {
569+
param_env,
570+
value: query::MethodAutoderefSteps { predefined_opaques_in_body, self_ty },
571+
} = goal;
572+
for (key, ty) in predefined_opaques_in_body {
573+
let prev =
574+
infcx.register_hidden_type_in_storage(key, ty::OpaqueHiddenType { span: DUMMY_SP, ty });
575+
// It may be possible that two entries in the opaque type storage end up
576+
// with the same key after resolving contained inference variables.
577+
//
578+
// We could put them in the duplicate list but don't have to. The opaques we
579+
// encounter here are already tracked in the caller, so there's no need to
580+
// also store them here. We'd take them out when computing the query response
581+
// and then discard them, as they're already present in the input.
582+
//
583+
// Ideally we'd drop duplicate opaque type definitions when computing
584+
// the canonical input. This is more annoying to implement and may cause a
585+
// perf regression, so we do it inside of the query for now.
586+
if let Some(prev) = prev {
587+
debug!(?key, ?ty, ?prev, "ignore duplicate in `opaque_types_storage`");
588+
}
589+
}
562590

563591
// If arbitrary self types is not enabled, we follow the chain of
564592
// `Deref<Target=T>`. If arbitrary self types is enabled, we instead
@@ -655,7 +683,8 @@ pub(crate) fn method_autoderef_steps<'tcx>(
655683
};
656684

657685
debug!("method_autoderef_steps: steps={:?} opt_bad_ty={:?}", steps, opt_bad_ty);
658-
686+
// Need to empty the opaque types storage before it gets dropped.
687+
let _ = infcx.take_opaque_types();
659688
MethodAutoderefStepsResult {
660689
steps: tcx.arena.alloc_from_iter(steps),
661690
opt_bad_ty: opt_bad_ty.map(|ty| &*tcx.arena.alloc(ty)),

compiler/rustc_middle/src/query/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ use crate::query::plumbing::{
124124
};
125125
use crate::traits::query::{
126126
CanonicalAliasGoal, CanonicalDropckOutlivesGoal, CanonicalImpliedOutlivesBoundsGoal,
127-
CanonicalPredicateGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal,
127+
CanonicalMethodAutoderefStepsGoal, CanonicalPredicateGoal, CanonicalTypeOpAscribeUserTypeGoal,
128128
CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, DropckConstraint,
129129
DropckOutlivesResult, MethodAutoderefStepsResult, NoSolution, NormalizationResult,
130130
OutlivesBound,
@@ -2559,9 +2559,9 @@ rustc_queries! {
25592559
}
25602560

25612561
query method_autoderef_steps(
2562-
goal: CanonicalTyGoal<'tcx>
2562+
goal: CanonicalMethodAutoderefStepsGoal<'tcx>
25632563
) -> MethodAutoderefStepsResult<'tcx> {
2564-
desc { "computing autoderef types for `{}`", goal.canonical.value.value }
2564+
desc { "computing autoderef types for `{}`", goal.canonical.value.value.self_ty }
25652565
}
25662566

25672567
/// Used by `-Znext-solver` to compute proof trees.

compiler/rustc_middle/src/traits/query.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_span::Span;
1010

1111
use crate::error::DropCheckOverflow;
1212
use crate::infer::canonical::{Canonical, CanonicalQueryInput, QueryResponse};
13+
use crate::traits::solve;
1314
pub use crate::traits::solve::NoSolution;
1415
use crate::ty::{self, GenericArg, Ty, TyCtxt};
1516

@@ -67,7 +68,16 @@ pub mod type_op {
6768
pub type CanonicalAliasGoal<'tcx> =
6869
CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>;
6970

70-
pub type CanonicalTyGoal<'tcx> = CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>;
71+
pub type CanonicalMethodAutoderefStepsGoal<'tcx> =
72+
CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, MethodAutoderefSteps<'tcx>>>;
73+
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
74+
pub struct MethodAutoderefSteps<'tcx> {
75+
/// The list of opaque types currently in the storage.
76+
///
77+
/// Only used by the new solver for now.
78+
pub predefined_opaques_in_body: solve::PredefinedOpaques<'tcx>,
79+
pub self_ty: Ty<'tcx>,
80+
}
7181

7282
pub type CanonicalPredicateGoal<'tcx> =
7383
CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>;

compiler/rustc_middle/src/ty/context.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
7474
use crate::thir::Thir;
7575
use crate::traits;
7676
use crate::traits::solve::{
77-
self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, QueryResult, inspect,
77+
self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, PredefinedOpaques,
78+
QueryResult, inspect,
7879
};
7980
use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
8081
use crate::ty::{
@@ -3127,6 +3128,14 @@ impl<'tcx> TyCtxt<'tcx> {
31273128
T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
31283129
}
31293130

3131+
pub fn mk_predefined_opaques_in_body_from_iter<I, T>(self, iter: I) -> T::Output
3132+
where
3133+
I: Iterator<Item = T>,
3134+
T: CollectAndApply<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>), PredefinedOpaques<'tcx>>,
3135+
{
3136+
T::collect_and_apply(iter, |xs| self.mk_predefined_opaques_in_body(xs))
3137+
}
3138+
31303139
pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
31313140
where
31323141
I: Iterator<Item = T>,

0 commit comments

Comments
 (0)