Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1633,8 +1633,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Expectation<'tcx>,
) -> Ty<'tcx> {
let rcvr_t = self.check_expr(rcvr);
// no need to check for bot/err -- callee does that
let rcvr_t = self.structurally_resolve_type(rcvr.span, rcvr_t);
let rcvr_t = self.try_structurally_resolve_type(rcvr.span, rcvr_t);

match self.lookup_method(rcvr_t, segment, segment.ident.span, expr, rcvr, args) {
Ok(method) => {
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_hir_typeck/src/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// Commit the autoderefs by calling `autoderef` again, but this
// time writing the results into the various typeck results.
let mut autoderef = self.autoderef(self.call_expr.span, unadjusted_self_ty);
let Some((ty, n)) = autoderef.nth(pick.autoderefs) else {
let Some((mut target, n)) = autoderef.nth(pick.autoderefs) else {
return Ty::new_error_with_message(
self.tcx,
DUMMY_SP,
Expand All @@ -182,8 +182,6 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
assert_eq!(n, pick.autoderefs);

let mut adjustments = self.adjust_steps(&autoderef);
let mut target = self.structurally_resolve_type(autoderef.span(), ty);

match pick.autoref_or_ptr_adjustment {
Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, unsize }) => {
let region = self.next_region_var(RegionVariableOrigin::Autoref(self.span));
Expand Down
267 changes: 230 additions & 37 deletions compiler/rustc_hir_typeck/src/method/probe.rs

Large diffs are not rendered by default.

20 changes: 19 additions & 1 deletion compiler/rustc_infer/src/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,29 @@ impl<'tcx> InferCtxt<'tcx> {
where
T: Debug + TypeFoldable<TyCtxt<'tcx>>,
{
// While we ignore region constraints and pending obligations,
// we do return constrained opaque types to avoid unconstrained
// inference variables in the response. This is important as we want
// to check that opaques in deref steps stay unconstrained.
//
// This doesn't handle the more general case for non-opaques as
// ambiguous `Projection` obligations have same the issue.
let opaque_types = if self.next_trait_solver() {
self.inner
.borrow_mut()
.opaque_type_storage
.iter_opaque_types()
.map(|(k, v)| (k, v.ty))
.collect()
} else {
vec![]
};

self.canonicalize_response(QueryResponse {
var_values: inference_vars,
region_constraints: QueryRegionConstraints::default(),
certainty: Certainty::Proven, // Ambiguities are OK!
opaque_types: vec![],
opaque_types,
value: answer,
})
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ macro_rules! arena_types {
rustc_middle::ty::EarlyBinder<'tcx, rustc_middle::ty::Ty<'tcx>>
>,
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<rustc_middle::ty::TyCtxt<'tcx>>,
[] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<rustc_middle::ty::TyCtxt<'tcx>>,
[decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap,
[] stripped_cfg_items: rustc_hir::attrs::StrippedCfgItem,
[] mod_child: rustc_middle::metadata::ModChild,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down
13 changes: 12 additions & 1 deletion compiler/rustc_middle/src/traits/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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>>>;
Expand Down Expand Up @@ -144,6 +154,7 @@ impl<'tcx> FromIterator<DropckConstraint<'tcx>> for DropckConstraint<'tcx> {
#[derive(Debug, HashStable)]
pub struct CandidateStep<'tcx> {
pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
pub self_ty_is_opaque: bool,
pub autoderefs: usize,
/// `true` if the type results from a dereference of a raw pointer.
/// when assembling candidates, we include these steps, but not when
Expand Down
45 changes: 2 additions & 43 deletions compiler/rustc_middle/src/traits/solve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc_type_ir as ir;
pub use rustc_type_ir::solve::*;

use crate::ty::{
self, FallibleTypeFolder, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
try_visit,
};

Expand All @@ -15,16 +15,7 @@ pub type CandidateSource<'tcx> = ir::solve::CandidateSource<TyCtxt<'tcx>>;
pub type CanonicalInput<'tcx, P = ty::Predicate<'tcx>> = ir::solve::CanonicalInput<TyCtxt<'tcx>, P>;
pub type CanonicalResponse<'tcx> = ir::solve::CanonicalResponse<TyCtxt<'tcx>>;

#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
pub struct PredefinedOpaques<'tcx>(pub(crate) Interned<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>);

impl<'tcx> std::ops::Deref for PredefinedOpaques<'tcx> {
type Target = PredefinedOpaquesData<TyCtxt<'tcx>>;

fn deref(&self) -> &Self::Target {
&self.0
}
}
pub type PredefinedOpaques<'tcx> = &'tcx ty::List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>;

#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
pub struct ExternalConstraints<'tcx>(
Expand Down Expand Up @@ -93,35 +84,3 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
self.normalization_nested_goals.visit_with(visitor)
}
}

// FIXME: Having to clone `region_constraints` for folding feels bad and
// probably isn't great wrt performance.
//
// Not sure how to fix this, maybe we should also intern `opaque_types` and
// `region_constraints` here or something.
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(FallibleTypeFolder::cx(folder).mk_predefined_opaques_in_body(PredefinedOpaquesData {
opaque_types: self
.opaque_types
.iter()
.map(|opaque| opaque.try_fold_with(folder))
.collect::<Result<_, F::Error>>()?,
}))
}

fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
TypeFolder::cx(folder).mk_predefined_opaques_in_body(PredefinedOpaquesData {
opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
})
}
}

impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
self.opaque_types.visit_with(visitor)
}
}
17 changes: 12 additions & 5 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ use crate::thir::Thir;
use crate::traits;
use crate::traits::solve::{
self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, PredefinedOpaques,
PredefinedOpaquesData, QueryResult, inspect,
QueryResult, inspect,
};
use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
use crate::ty::{
Expand Down Expand Up @@ -116,7 +116,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {

fn mk_predefined_opaques_in_body(
self,
data: PredefinedOpaquesData<Self>,
data: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)],
) -> Self::PredefinedOpaques {
self.mk_predefined_opaques_in_body(data)
}
Expand Down Expand Up @@ -941,7 +941,7 @@ pub struct CtxtInterners<'tcx> {
layout: InternedSet<'tcx, LayoutData<FieldIdx, VariantIdx>>,
adt_def: InternedSet<'tcx, AdtDefData>,
external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>,
predefined_opaques_in_body: InternedSet<'tcx, List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>>,
fields: InternedSet<'tcx, List<FieldIdx>>,
local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
Expand Down Expand Up @@ -2748,8 +2748,6 @@ direct_interners! {
adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
ExternalConstraints -> ExternalConstraints<'tcx>,
predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>):
PredefinedOpaques -> PredefinedOpaques<'tcx>,
}

macro_rules! slice_interners {
Expand Down Expand Up @@ -2786,6 +2784,7 @@ slice_interners!(
offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
patterns: pub mk_patterns(Pattern<'tcx>),
outlives: pub mk_outlives(ty::ArgOutlivesPredicate<'tcx>),
predefined_opaques_in_body: pub mk_predefined_opaques_in_body((ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)),
);

impl<'tcx> TyCtxt<'tcx> {
Expand Down Expand Up @@ -3129,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>,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,7 @@ macro_rules! list_fold {

list_fold! {
&'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> : mk_poly_existential_predicates,
&'tcx ty::List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>: mk_predefined_opaques_in_body,
&'tcx ty::List<PlaceElem<'tcx>> : mk_place_elems,
&'tcx ty::List<ty::Pattern<'tcx>> : mk_patterns,
&'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>> : mk_outlives,
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_next_trait_solver/src/canonical/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::delegate::SolverDelegate;
use crate::resolve::eager_resolve_vars;
use crate::solve::{
CanonicalInput, CanonicalResponse, Certainty, ExternalConstraintsData, Goal,
NestedNormalizationGoals, PredefinedOpaquesData, QueryInput, Response, inspect,
NestedNormalizationGoals, QueryInput, Response, inspect,
};

pub mod canonicalizer;
Expand Down Expand Up @@ -53,7 +53,7 @@ impl<I: Interner, T> ResponseT<I> for inspect::State<I, T> {
pub(super) fn canonicalize_goal<D, I>(
delegate: &D,
goal: Goal<I, I::Predicate>,
opaque_types: Vec<(ty::OpaqueTypeKey<I>, I::Ty)>,
opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)],
) -> (Vec<I::GenericArg>, CanonicalInput<I, I::Predicate>)
where
D: SolverDelegate<Interner = I>,
Expand All @@ -65,9 +65,7 @@ where
&mut orig_values,
QueryInput {
goal,
predefined_opaques_in_body: delegate
.cx()
.mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }),
predefined_opaques_in_body: delegate.cx().mk_predefined_opaques_in_body(opaque_types),
},
);
let query_input = ty::CanonicalQueryInput { canonical, typing_mode: delegate.typing_mode() };
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ where
D: SolverDelegate<Interner = I>,
I: Interner,
{
#[instrument(level = "debug", skip(self))]
#[instrument(level = "debug", skip(self), ret)]
fn evaluate_root_goal(
&self,
goal: Goal<I, I::Predicate>,
Expand All @@ -206,6 +206,7 @@ where
})
}

#[instrument(level = "debug", skip(self), ret)]
fn root_goal_may_hold_opaque_types_jank(
&self,
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
Expand Down Expand Up @@ -357,7 +358,7 @@ where
f: impl FnOnce(&mut EvalCtxt<'_, D>, Goal<I, I::Predicate>) -> R,
) -> R {
let (ref delegate, input, var_values) = D::build_with_canonical(cx, &canonical_input);
for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
for (key, ty) in input.predefined_opaques_in_body.iter() {
let prev = delegate.register_hidden_type_in_storage(key, ty, I::Span::dummy());
// It may be possible that two entries in the opaque type storage end up
// with the same key after resolving contained inference variables.
Expand Down Expand Up @@ -467,7 +468,7 @@ where
let opaque_types = self.delegate.clone_opaque_types_lookup_table();
let (goal, opaque_types) = eager_resolve_vars(self.delegate, (goal, opaque_types));

let (orig_values, canonical_goal) = canonicalize_goal(self.delegate, goal, opaque_types);
let (orig_values, canonical_goal) = canonicalize_goal(self.delegate, goal, &opaque_types);
let canonical_result = self.search_graph.evaluate_goal(
self.cx(),
canonical_goal,
Expand Down Expand Up @@ -548,7 +549,6 @@ where
.canonical
.value
.predefined_opaques_in_body
.opaque_types
.len(),
stalled_vars,
sub_roots,
Expand Down Expand Up @@ -1557,7 +1557,7 @@ pub(super) fn evaluate_root_goal_for_proof_tree<D: SolverDelegate<Interner = I>,
let opaque_types = delegate.clone_opaque_types_lookup_table();
let (goal, opaque_types) = eager_resolve_vars(delegate, (goal, opaque_types));

let (orig_values, canonical_goal) = canonicalize_goal(delegate, goal, opaque_types);
let (orig_values, canonical_goal) = canonicalize_goal(delegate, goal, &opaque_types);

let (canonical_result, final_revision) =
delegate.cx().evaluate_root_goal_for_proof_tree_raw(canonical_goal);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_next_trait_solver/src/solve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ where
}

/// The result of evaluating a goal.
#[derive_where(Debug; I: Interner)]
pub struct GoalEvaluation<I: Interner> {
/// The goal we've evaluated. This is the input goal, but potentially with its
/// inference variables resolved. This never applies any inference constraints
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use rustc_infer::traits::solve::Goal;
use rustc_macros::extension;
use rustc_middle::span_bug;
use rustc_middle::{span_bug, ty};
use rustc_next_trait_solver::solve::SolverDelegateEvalExt;

use crate::infer::InferCtxt;
Expand All @@ -22,7 +22,7 @@ impl<'tcx> InferCtxt<'tcx> {
/// for more details.
fn predicate_may_hold_opaque_types_jank(&self, obligation: &PredicateObligation<'tcx>) -> bool {
if self.next_trait_solver() {
<&SolverDelegate<'tcx>>::from(self).root_goal_may_hold_opaque_types_jank(Goal::new(
self.goal_may_hold_opaque_types_jank(Goal::new(
self.tcx,
obligation.param_env,
obligation.predicate,
Expand All @@ -32,6 +32,13 @@ impl<'tcx> InferCtxt<'tcx> {
}
}

/// See the comment on [OpaqueTypesJank](crate::solve::OpaqueTypesJank)
/// for more details.
fn goal_may_hold_opaque_types_jank(&self, goal: Goal<'tcx, ty::Predicate<'tcx>>) -> bool {
assert!(self.next_trait_solver());
<&SolverDelegate<'tcx>>::from(self).root_goal_may_hold_opaque_types_jank(goal)
}

/// Evaluates whether the predicate can be satisfied in the given
/// `ParamEnv`, and returns `false` if not certain. However, this is
/// not entirely accurate if inference variables are involved.
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_type_ir/src/interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ use crate::inherent::*;
use crate::ir_print::IrPrint;
use crate::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem};
use crate::relate::Relate;
use crate::solve::{
CanonicalInput, ExternalConstraintsData, PredefinedOpaquesData, QueryResult, inspect,
};
use crate::solve::{CanonicalInput, ExternalConstraintsData, QueryResult, inspect};
use crate::visit::{Flags, TypeVisitable};
use crate::{self as ty, CanonicalParamEnvCacheEntry, search_graph};

Expand Down Expand Up @@ -70,10 +68,10 @@ pub trait Interner:
+ Hash
+ Eq
+ TypeFoldable<Self>
+ Deref<Target = PredefinedOpaquesData<Self>>;
+ SliceLike<Item = (ty::OpaqueTypeKey<Self>, Self::Ty)>;
fn mk_predefined_opaques_in_body(
self,
data: PredefinedOpaquesData<Self>,
data: &[(ty::OpaqueTypeKey<Self>, Self::Ty)],
) -> Self::PredefinedOpaques;

type LocalDefIds: Copy
Expand Down
Loading
Loading