1
Fork 0

Replace Deref bounds on Interner in favor of a SliceLike trait

This commit is contained in:
Michael Goulet 2024-06-21 13:55:21 -04:00
parent f26cc349d9
commit 24e41f1d13
22 changed files with 221 additions and 159 deletions

View file

@ -133,6 +133,20 @@ impl<H, T> RawList<H, T> {
} }
} }
impl<'a, H, T: Copy> rustc_type_ir::inherent::SliceLike for &'a RawList<H, T> {
type Item = T;
type IntoIter = iter::Copied<<&'a [T] as IntoIterator>::IntoIter>;
fn iter(self) -> Self::IntoIter {
(*self).iter()
}
fn as_slice(&self) -> &[Self::Item] {
(*self).as_slice()
}
}
macro_rules! impl_list_empty { macro_rules! impl_list_empty {
($header_ty:ty, $header_init:expr) => { ($header_ty:ty, $header_init:expr) => {
impl<T> RawList<$header_ty, T> { impl<T> RawList<$header_ty, T> {

View file

@ -527,7 +527,7 @@ where
}; };
for assumption in for assumption in
self.cx().item_bounds(alias_ty.def_id).iter_instantiated(self.cx(), &alias_ty.args) self.cx().item_bounds(alias_ty.def_id).iter_instantiated(self.cx(), alias_ty.args)
{ {
candidates.extend(G::probe_and_consider_implied_clause( candidates.extend(G::probe_and_consider_implied_clause(
self, self,
@ -603,7 +603,7 @@ where
// Consider all of the auto-trait and projection bounds, which don't // Consider all of the auto-trait and projection bounds, which don't
// need to be recorded as a `BuiltinImplSource::Object` since they don't // need to be recorded as a `BuiltinImplSource::Object` since they don't
// really have a vtable base... // really have a vtable base...
for bound in bounds { for bound in bounds.iter() {
match bound.skip_binder() { match bound.skip_binder() {
ty::ExistentialPredicate::Trait(_) => { ty::ExistentialPredicate::Trait(_) => {
// Skip principal // Skip principal

View file

@ -58,7 +58,7 @@ where
ty::Tuple(tys) => { ty::Tuple(tys) => {
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
Ok(tys.into_iter().map(ty::Binder::dummy).collect()) Ok(tys.iter().map(ty::Binder::dummy).collect())
} }
ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]), ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]),
@ -79,23 +79,21 @@ where
.cx() .cx()
.bound_coroutine_hidden_types(def_id) .bound_coroutine_hidden_types(def_id)
.into_iter() .into_iter()
.map(|bty| bty.instantiate(tcx, &args)) .map(|bty| bty.instantiate(tcx, args))
.collect()), .collect()),
// For `PhantomData<T>`, we pass `T`. // For `PhantomData<T>`, we pass `T`.
ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![ty::Binder::dummy(args.type_at(0))]), ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![ty::Binder::dummy(args.type_at(0))]),
ty::Adt(def, args) => Ok(def ty::Adt(def, args) => {
.all_field_tys(tcx) Ok(def.all_field_tys(tcx).iter_instantiated(tcx, args).map(ty::Binder::dummy).collect())
.iter_instantiated(tcx, &args) }
.map(ty::Binder::dummy)
.collect()),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
// We can resolve the `impl Trait` to its concrete type, // We can resolve the `impl Trait` to its concrete type,
// which enforces a DAG between the functions requiring // which enforces a DAG between the functions requiring
// the auto trait bounds in question. // the auto trait bounds in question.
Ok(vec![ty::Binder::dummy(tcx.type_of(def_id).instantiate(tcx, &args))]) Ok(vec![ty::Binder::dummy(tcx.type_of(def_id).instantiate(tcx, args))])
} }
} }
} }
@ -147,7 +145,7 @@ where
// impl Sized for () // impl Sized for ()
// impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1 // impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1
ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |&ty| vec![ty::Binder::dummy(ty)])), ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |ty| vec![ty::Binder::dummy(ty)])),
// impl Sized for Adt<Args...> where sized_constraint(Adt)<Args...>: Sized // impl Sized for Adt<Args...> where sized_constraint(Adt)<Args...>: Sized
// `sized_constraint(Adt)` is the deepest struct trail that can be determined // `sized_constraint(Adt)` is the deepest struct trail that can be determined
@ -160,7 +158,7 @@ where
// if the ADT is sized for all possible args. // if the ADT is sized for all possible args.
ty::Adt(def, args) => { ty::Adt(def, args) => {
if let Some(sized_crit) = def.sized_constraint(ecx.cx()) { if let Some(sized_crit) = def.sized_constraint(ecx.cx()) {
Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.cx(), &args))]) Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.cx(), args))])
} else { } else {
Ok(vec![]) Ok(vec![])
} }
@ -213,7 +211,7 @@ where
} }
// impl Copy/Clone for (T1, T2, .., Tn) where T1: Copy/Clone, T2: Copy/Clone, .. Tn: Copy/Clone // impl Copy/Clone for (T1, T2, .., Tn) where T1: Copy/Clone, T2: Copy/Clone, .. Tn: Copy/Clone
ty::Tuple(tys) => Ok(tys.into_iter().map(ty::Binder::dummy).collect()), ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()),
// impl Copy/Clone for Closure where Self::TupledUpvars: Copy/Clone // impl Copy/Clone for Closure where Self::TupledUpvars: Copy/Clone
ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]), ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]),
@ -242,7 +240,7 @@ where
.cx() .cx()
.bound_coroutine_hidden_types(def_id) .bound_coroutine_hidden_types(def_id)
.into_iter() .into_iter()
.map(|bty| bty.instantiate(ecx.cx(), &args)) .map(|bty| bty.instantiate(ecx.cx(), args))
.collect()), .collect()),
} }
} }
@ -259,7 +257,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
let sig = tcx.fn_sig(def_id); let sig = tcx.fn_sig(def_id);
if sig.skip_binder().is_fn_trait_compatible() && !tcx.has_target_features(def_id) { if sig.skip_binder().is_fn_trait_compatible() && !tcx.has_target_features(def_id) {
Ok(Some( Ok(Some(
sig.instantiate(tcx, &args) sig.instantiate(tcx, args)
.map_bound(|sig| (Ty::new_tup(tcx, &sig.inputs()), sig.output())), .map_bound(|sig| (Ty::new_tup(tcx, &sig.inputs()), sig.output())),
)) ))
} else { } else {
@ -669,7 +667,7 @@ where
let tcx = ecx.cx(); let tcx = ecx.cx();
let mut requirements = vec![]; let mut requirements = vec![];
requirements requirements
.extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, &trait_ref.args)); .extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, trait_ref.args));
// FIXME(associated_const_equality): Also add associated consts to // FIXME(associated_const_equality): Also add associated consts to
// the requirements here. // the requirements here.
@ -680,13 +678,12 @@ where
continue; continue;
} }
requirements.extend( requirements
tcx.item_bounds(associated_type_def_id).iter_instantiated(tcx, &trait_ref.args), .extend(tcx.item_bounds(associated_type_def_id).iter_instantiated(tcx, trait_ref.args));
);
} }
let mut replace_projection_with = HashMap::default(); let mut replace_projection_with = HashMap::default();
for bound in object_bounds { for bound in object_bounds.iter() {
if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() { if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() {
let proj = proj.with_self_ty(tcx, trait_ref.self_ty()); let proj = proj.with_self_ty(tcx, trait_ref.self_ty());
let old_ty = replace_projection_with.insert(proj.def_id(), bound.rebind(proj)); let old_ty = replace_projection_with.insert(proj.def_id(), bound.rebind(proj));

View file

@ -267,7 +267,9 @@ where
// We therefore instantiate the existential variable in the canonical response with the // We therefore instantiate the existential variable in the canonical response with the
// inference variable of the input right away, which is more performant. // inference variable of the input right away, which is more performant.
let mut opt_values = IndexVec::from_elem_n(None, response.variables.len()); let mut opt_values = IndexVec::from_elem_n(None, response.variables.len());
for (original_value, result_value) in iter::zip(original_values, var_values.var_values) { for (original_value, result_value) in
iter::zip(original_values, var_values.var_values.iter())
{
match result_value.kind() { match result_value.kind() {
ty::GenericArgKind::Type(t) => { ty::GenericArgKind::Type(t) => {
if let ty::Bound(debruijn, b) = t.kind() { if let ty::Bound(debruijn, b) = t.kind() {
@ -291,7 +293,7 @@ where
} }
let var_values = delegate.cx().mk_args_from_iter( let var_values = delegate.cx().mk_args_from_iter(
response.variables.into_iter().enumerate().map(|(index, info)| { response.variables.iter().enumerate().map(|(index, info)| {
if info.universe() != ty::UniverseIndex::ROOT { if info.universe() != ty::UniverseIndex::ROOT {
// A variable from inside a binder of the query. While ideally these shouldn't // A variable from inside a binder of the query. While ideally these shouldn't
// exist at all (see the FIXME at the start of this method), we have to deal with // exist at all (see the FIXME at the start of this method), we have to deal with
@ -344,7 +346,7 @@ where
) { ) {
assert_eq!(original_values.len(), var_values.len()); assert_eq!(original_values.len(), var_values.len());
for (&orig, response) in iter::zip(original_values, var_values.var_values) { for (&orig, response) in iter::zip(original_values, var_values.var_values.iter()) {
let goals = let goals =
delegate.eq_structurally_relating_aliases(param_env, orig, response).unwrap(); delegate.eq_structurally_relating_aliases(param_env, orig, response).unwrap();
assert!(goals.is_empty()); assert!(goals.is_empty());
@ -413,7 +415,8 @@ where
// In case any fresh inference variables have been created between `state` // In case any fresh inference variables have been created between `state`
// and the previous instantiation, extend `orig_values` for it. // and the previous instantiation, extend `orig_values` for it.
assert!(orig_values.len() <= state.value.var_values.len()); assert!(orig_values.len() <= state.value.var_values.len());
for &arg in &state.value.var_values.var_values[orig_values.len()..state.value.var_values.len()] for &arg in &state.value.var_values.var_values.as_slice()
[orig_values.len()..state.value.var_values.len()]
{ {
// FIXME: This is so ugly. // FIXME: This is so ugly.
let unconstrained = delegate.fresh_var_for_kind_with_span(arg, span); let unconstrained = delegate.fresh_var_for_kind_with_span(arg, span);

View file

@ -875,7 +875,7 @@ where
pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs { pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs {
let args = self.delegate.fresh_args_for_item(def_id); let args = self.delegate.fresh_args_for_item(def_id);
for arg in args { for arg in args.iter() {
self.inspect.add_var_value(arg); self.inspect.add_var_value(arg);
} }
args args
@ -979,7 +979,7 @@ where
result: *result, result: *result,
}) })
.enter(|ecx| { .enter(|ecx| {
for (a, b) in std::iter::zip(candidate_key.args, key.args) { for (a, b) in std::iter::zip(candidate_key.args.iter(), key.args.iter()) {
ecx.eq(param_env, a, b)?; ecx.eq(param_env, a, b)?;
} }
ecx.eq(param_env, candidate_ty, ty)?; ecx.eq(param_env, candidate_ty, ty)?;

View file

@ -7,6 +7,7 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem; use std::mem;
use rustc_type_ir::inherent::*;
use rustc_type_ir::{self as ty, Interner}; use rustc_type_ir::{self as ty, Interner};
use crate::delegate::SolverDelegate; use crate::delegate::SolverDelegate;

View file

@ -182,7 +182,7 @@ where
return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
} }
ty::ConstKind::Unevaluated(uv) => { ty::ConstKind::Unevaluated(uv) => {
self.cx().type_of(uv.def).instantiate(self.cx(), &uv.args) self.cx().type_of(uv.def).instantiate(self.cx(), uv.args)
} }
ty::ConstKind::Expr(_) => unimplemented!( ty::ConstKind::Expr(_) => unimplemented!(
"`feature(generic_const_exprs)` is not supported in the new trait solver" "`feature(generic_const_exprs)` is not supported in the new trait solver"

View file

@ -29,7 +29,7 @@ where
self.eq( self.eq(
goal.param_env, goal.param_env,
inherent.self_ty(), inherent.self_ty(),
tcx.type_of(impl_def_id).instantiate(tcx, &impl_args), tcx.type_of(impl_def_id).instantiate(tcx, impl_args),
)?; )?;
// Equate IAT with the RHS of the project goal // Equate IAT with the RHS of the project goal
@ -44,11 +44,11 @@ where
self.add_goals( self.add_goals(
GoalSource::Misc, GoalSource::Misc,
tcx.predicates_of(inherent.def_id) tcx.predicates_of(inherent.def_id)
.iter_instantiated(tcx, &inherent_args) .iter_instantiated(tcx, inherent_args)
.map(|pred| goal.with(tcx, pred)), .map(|pred| goal.with(tcx, pred)),
); );
let normalized = tcx.type_of(inherent.def_id).instantiate(tcx, &inherent_args); let normalized = tcx.type_of(inherent.def_id).instantiate(tcx, inherent_args);
self.instantiate_normalizes_to_term(goal, normalized.into()); self.instantiate_normalizes_to_term(goal, normalized.into());
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
} }

View file

@ -121,7 +121,7 @@ where
ecx.add_goals( ecx.add_goals(
GoalSource::Misc, GoalSource::Misc,
tcx.own_predicates_of(goal.predicate.def_id()) tcx.own_predicates_of(goal.predicate.def_id())
.iter_instantiated(tcx, &goal.predicate.alias.args) .iter_instantiated(tcx, goal.predicate.alias.args)
.map(|pred| goal.with(tcx, pred)), .map(|pred| goal.with(tcx, pred)),
); );
@ -163,13 +163,13 @@ where
ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
let impl_args = ecx.fresh_args_for_item(impl_def_id); let impl_args = ecx.fresh_args_for_item(impl_def_id);
let impl_trait_ref = impl_trait_ref.instantiate(tcx, &impl_args); let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args);
ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?; ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
let where_clause_bounds = tcx let where_clause_bounds = tcx
.predicates_of(impl_def_id) .predicates_of(impl_def_id)
.iter_instantiated(tcx, &impl_args) .iter_instantiated(tcx, impl_args)
.map(|pred| goal.with(tcx, pred)); .map(|pred| goal.with(tcx, pred));
ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
@ -177,7 +177,7 @@ where
ecx.add_goals( ecx.add_goals(
GoalSource::Misc, GoalSource::Misc,
tcx.own_predicates_of(goal.predicate.def_id()) tcx.own_predicates_of(goal.predicate.def_id())
.iter_instantiated(tcx, &goal.predicate.alias.args) .iter_instantiated(tcx, goal.predicate.alias.args)
.map(|pred| goal.with(tcx, pred)), .map(|pred| goal.with(tcx, pred)),
); );
@ -254,7 +254,7 @@ where
kind => panic!("expected projection, found {kind:?}"), kind => panic!("expected projection, found {kind:?}"),
}; };
ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, &target_args)); ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, target_args));
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}) })
} }
@ -467,7 +467,7 @@ where
tupled_inputs_ty, tupled_inputs_ty,
tupled_upvars_ty, tupled_upvars_ty,
coroutine_captures_by_ref_ty, coroutine_captures_by_ref_ty,
] = **goal.predicate.alias.args ] = *goal.predicate.alias.args.as_slice()
else { else {
panic!(); panic!();
}; };
@ -567,14 +567,14 @@ where
ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(tcx) { ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(tcx) {
None => Ty::new_unit(tcx), None => Ty::new_unit(tcx),
Some(tail_ty) => { Some(tail_ty) => {
Ty::new_projection(tcx, metadata_def_id, [tail_ty.instantiate(tcx, &args)]) Ty::new_projection(tcx, metadata_def_id, [tail_ty.instantiate(tcx, args)])
} }
}, },
ty::Adt(_, _) => Ty::new_unit(tcx), ty::Adt(_, _) => Ty::new_unit(tcx),
ty::Tuple(elements) => match elements.last() { ty::Tuple(elements) => match elements.last() {
None => Ty::new_unit(tcx), None => Ty::new_unit(tcx),
Some(&tail_ty) => Ty::new_projection(tcx, metadata_def_id, [tail_ty]), Some(tail_ty) => Ty::new_projection(tcx, metadata_def_id, [tail_ty]),
}, },
ty::Infer( ty::Infer(
@ -895,7 +895,7 @@ where
} else { } else {
let target_args = self.fresh_args_for_item(target_container_def_id); let target_args = self.fresh_args_for_item(target_container_def_id);
let target_trait_ref = let target_trait_ref =
tcx.impl_trait_ref(target_container_def_id).instantiate(tcx, &target_args); tcx.impl_trait_ref(target_container_def_id).instantiate(tcx, target_args);
// Relate source impl to target impl by equating trait refs. // Relate source impl to target impl by equating trait refs.
self.eq(goal.param_env, impl_trait_ref, target_trait_ref)?; self.eq(goal.param_env, impl_trait_ref, target_trait_ref)?;
// Also add predicates since they may be needed to constrain the // Also add predicates since they may be needed to constrain the
@ -903,7 +903,7 @@ where
self.add_goals( self.add_goals(
GoalSource::Misc, GoalSource::Misc,
tcx.predicates_of(target_container_def_id) tcx.predicates_of(target_container_def_id)
.iter_instantiated(tcx, &target_args) .iter_instantiated(tcx, target_args)
.map(|pred| goal.with(tcx, pred)), .map(|pred| goal.with(tcx, pred)),
); );
goal.predicate.alias.args.rebase_onto(tcx, impl_trait_ref.def_id, target_args) goal.predicate.alias.args.rebase_onto(tcx, impl_trait_ref.def_id, target_args)

View file

@ -86,7 +86,7 @@ where
} }
(Reveal::All, _) => { (Reveal::All, _) => {
// FIXME: Add an assertion that opaque type storage is empty. // FIXME: Add an assertion that opaque type storage is empty.
let actual = tcx.type_of(opaque_ty.def_id).instantiate(tcx, &opaque_ty.args); let actual = tcx.type_of(opaque_ty.def_id).instantiate(tcx, opaque_ty.args);
self.eq(goal.param_env, expected, actual)?; self.eq(goal.param_env, expected, actual)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
} }
@ -102,7 +102,7 @@ pub fn uses_unique_placeholders_ignoring_regions<I: Interner>(
args: I::GenericArgs, args: I::GenericArgs,
) -> Result<(), NotUniqueParam<I>> { ) -> Result<(), NotUniqueParam<I>> {
let mut seen = GrowableBitSet::default(); let mut seen = GrowableBitSet::default();
for arg in args { for arg in args.iter() {
match arg.kind() { match arg.kind() {
// Ignore regions, since we can't resolve those in a canonicalized // Ignore regions, since we can't resolve those in a canonicalized
// query in the trait solver. // query in the trait solver.

View file

@ -25,11 +25,11 @@ where
self.add_goals( self.add_goals(
GoalSource::Misc, GoalSource::Misc,
tcx.predicates_of(weak_ty.def_id) tcx.predicates_of(weak_ty.def_id)
.iter_instantiated(tcx, &weak_ty.args) .iter_instantiated(tcx, weak_ty.args)
.map(|pred| goal.with(tcx, pred)), .map(|pred| goal.with(tcx, pred)),
); );
let actual = tcx.type_of(weak_ty.def_id).instantiate(tcx, &weak_ty.args); let actual = tcx.type_of(weak_ty.def_id).instantiate(tcx, weak_ty.args);
self.instantiate_normalizes_to_term(goal, actual.into()); self.instantiate_normalizes_to_term(goal, actual.into());
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)

View file

@ -77,12 +77,12 @@ where
ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
let impl_args = ecx.fresh_args_for_item(impl_def_id); let impl_args = ecx.fresh_args_for_item(impl_def_id);
ecx.record_impl_args(impl_args); ecx.record_impl_args(impl_args);
let impl_trait_ref = impl_trait_ref.instantiate(tcx, &impl_args); let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args);
ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?; ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
let where_clause_bounds = tcx let where_clause_bounds = tcx
.predicates_of(impl_def_id) .predicates_of(impl_def_id)
.iter_instantiated(tcx, &impl_args) .iter_instantiated(tcx, impl_args)
.map(|pred| goal.with(tcx, pred)); .map(|pred| goal.with(tcx, pred));
ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
@ -186,7 +186,7 @@ where
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
let nested_obligations = tcx let nested_obligations = tcx
.predicates_of(goal.predicate.def_id()) .predicates_of(goal.predicate.def_id())
.iter_instantiated(tcx, &goal.predicate.trait_ref.args) .iter_instantiated(tcx, goal.predicate.trait_ref.args)
.map(|p| goal.with(tcx, p)); .map(|p| goal.with(tcx, p));
// FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`? // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
ecx.add_goals(GoalSource::Misc, nested_obligations); ecx.add_goals(GoalSource::Misc, nested_obligations);
@ -373,7 +373,7 @@ where
ecx: &mut EvalCtxt<'_, D>, ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>, goal: Goal<I, Self>,
) -> Result<Candidate<I>, NoSolution> { ) -> Result<Candidate<I>, NoSolution> {
let [closure_fn_kind_ty, goal_kind_ty] = **goal.predicate.trait_ref.args else { let [closure_fn_kind_ty, goal_kind_ty] = *goal.predicate.trait_ref.args.as_slice() else {
panic!(); panic!();
}; };
@ -783,7 +783,7 @@ where
// (i.e. the principal, all of the associated types match, and any auto traits) // (i.e. the principal, all of the associated types match, and any auto traits)
ecx.add_goals( ecx.add_goals(
GoalSource::ImplWhereBound, GoalSource::ImplWhereBound,
b_data.into_iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))), b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))),
); );
// The type must be `Sized` to be unsized. // The type must be `Sized` to be unsized.
@ -851,7 +851,7 @@ where
}; };
self.probe_trait_candidate(source).enter(|ecx| { self.probe_trait_candidate(source).enter(|ecx| {
for bound in b_data { for bound in b_data.iter() {
match bound.skip_binder() { match bound.skip_binder() {
// Check that a's supertrait (upcast_principal) is compatible // Check that a's supertrait (upcast_principal) is compatible
// with the target (b_ty). // with the target (b_ty).
@ -953,18 +953,15 @@ where
let tail_field_ty = def.struct_tail_ty(tcx).unwrap(); let tail_field_ty = def.struct_tail_ty(tcx).unwrap();
let a_tail_ty = tail_field_ty.instantiate(tcx, &a_args); let a_tail_ty = tail_field_ty.instantiate(tcx, a_args);
let b_tail_ty = tail_field_ty.instantiate(tcx, &b_args); let b_tail_ty = tail_field_ty.instantiate(tcx, b_args);
// Instantiate just the unsizing params from B into A. The type after // Instantiate just the unsizing params from B into A. The type after
// this instantiation must be equal to B. This is so we don't unsize // this instantiation must be equal to B. This is so we don't unsize
// unrelated type parameters. // unrelated type parameters.
let new_a_args = tcx.mk_args_from_iter( let new_a_args = tcx.mk_args_from_iter(a_args.iter().enumerate().map(|(i, a)| {
a_args if unsizing_params.contains(i as u32) { b_args.get(i).unwrap() } else { a }
.iter() }));
.enumerate()
.map(|(i, a)| if unsizing_params.contains(i as u32) { b_args[i] } else { *a }),
);
let unsized_a_ty = Ty::new_adt(tcx, def, new_a_args); let unsized_a_ty = Ty::new_adt(tcx, def, new_a_args);
// Finally, we require that `TailA: Unsize<TailB>` for the tail field // Finally, we require that `TailA: Unsize<TailB>` for the tail field
@ -1005,7 +1002,7 @@ where
let Goal { predicate: (_a_ty, b_ty), .. } = goal; let Goal { predicate: (_a_ty, b_ty), .. } = goal;
let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap(); let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap();
let &b_last_ty = b_tys.last().unwrap(); let b_last_ty = b_tys.last().unwrap();
// Instantiate just the tail field of B., and require that they're equal. // Instantiate just the tail field of B., and require that they're equal.
let unsized_a_ty = let unsized_a_ty =

View file

@ -320,7 +320,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
if self.bound_vars.len() <= idx { if self.bound_vars.len() <= idx {
panic!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars); panic!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars);
} }
bound_ty.assert_eq(self.bound_vars[idx]); bound_ty.assert_eq(self.bound_vars.get(idx).unwrap());
} }
_ => {} _ => {}
}; };
@ -335,7 +335,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
if self.bound_vars.len() <= idx { if self.bound_vars.len() <= idx {
panic!("Not enough bound vars: {:?} not found in {:?}", r, self.bound_vars); panic!("Not enough bound vars: {:?} not found in {:?}", r, self.bound_vars);
} }
br.assert_eq(self.bound_vars[idx]); br.assert_eq(self.bound_vars.get(idx).unwrap());
} }
_ => (), _ => (),
@ -435,15 +435,14 @@ impl<I: Interner, T> EarlyBinder<I, Option<T>> {
} }
} }
impl<'s, I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter> impl<I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter>
where where
Iter::Item: TypeFoldable<I>, Iter::Item: TypeFoldable<I>,
{ {
pub fn iter_instantiated( pub fn iter_instantiated<A>(self, tcx: I, args: A) -> IterInstantiated<I, Iter, A>
self, where
tcx: I, A: SliceLike<Item = I::GenericArg>,
args: &'s [I::GenericArg], {
) -> IterInstantiated<'s, I, Iter> {
IterInstantiated { it: self.value.into_iter(), tcx, args } IterInstantiated { it: self.value.into_iter(), tcx, args }
} }
@ -454,15 +453,16 @@ where
} }
} }
pub struct IterInstantiated<'s, I: Interner, Iter: IntoIterator> { pub struct IterInstantiated<I: Interner, Iter: IntoIterator, A> {
it: Iter::IntoIter, it: Iter::IntoIter,
tcx: I, tcx: I,
args: &'s [I::GenericArg], args: A,
} }
impl<I: Interner, Iter: IntoIterator> Iterator for IterInstantiated<'_, I, Iter> impl<I: Interner, Iter: IntoIterator, A> Iterator for IterInstantiated<I, Iter, A>
where where
Iter::Item: TypeFoldable<I>, Iter::Item: TypeFoldable<I>,
A: SliceLike<Item = I::GenericArg>,
{ {
type Item = Iter::Item; type Item = Iter::Item;
@ -478,10 +478,11 @@ where
} }
} }
impl<I: Interner, Iter: IntoIterator> DoubleEndedIterator for IterInstantiated<'_, I, Iter> impl<I: Interner, Iter: IntoIterator, A> DoubleEndedIterator for IterInstantiated<I, Iter, A>
where where
Iter::IntoIter: DoubleEndedIterator, Iter::IntoIter: DoubleEndedIterator,
Iter::Item: TypeFoldable<I>, Iter::Item: TypeFoldable<I>,
A: SliceLike<Item = I::GenericArg>,
{ {
fn next_back(&mut self) -> Option<Self::Item> { fn next_back(&mut self) -> Option<Self::Item> {
Some( Some(
@ -491,10 +492,11 @@ where
} }
} }
impl<I: Interner, Iter: IntoIterator> ExactSizeIterator for IterInstantiated<'_, I, Iter> impl<I: Interner, Iter: IntoIterator, A> ExactSizeIterator for IterInstantiated<I, Iter, A>
where where
Iter::IntoIter: ExactSizeIterator, Iter::IntoIter: ExactSizeIterator,
Iter::Item: TypeFoldable<I>, Iter::Item: TypeFoldable<I>,
A: SliceLike<Item = I::GenericArg>,
{ {
} }
@ -589,8 +591,11 @@ impl<I: Interner, T: Iterator> Iterator for EarlyBinderIter<I, T> {
} }
impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> { impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> {
pub fn instantiate(self, tcx: I, args: &[I::GenericArg]) -> T { pub fn instantiate<A>(self, tcx: I, args: A) -> T
let mut folder = ArgFolder { tcx, args, binders_passed: 0 }; where
A: SliceLike<Item = I::GenericArg>,
{
let mut folder = ArgFolder { tcx, args: args.as_slice(), binders_passed: 0 };
self.value.fold_with(&mut folder) self.value.fold_with(&mut folder)
} }

View file

@ -283,7 +283,7 @@ pub struct CanonicalVarValues<I: Interner> {
impl<I: Interner> CanonicalVarValues<I> { impl<I: Interner> CanonicalVarValues<I> {
pub fn is_identity(&self) -> bool { pub fn is_identity(&self) -> bool {
self.var_values.into_iter().enumerate().all(|(bv, arg)| match arg.kind() { self.var_values.iter().enumerate().all(|(bv, arg)| match arg.kind() {
ty::GenericArgKind::Lifetime(r) => { ty::GenericArgKind::Lifetime(r) => {
matches!(r.kind(), ty::ReBound(ty::INNERMOST, br) if br.var().as_usize() == bv) matches!(r.kind(), ty::ReBound(ty::INNERMOST, br) if br.var().as_usize() == bv)
} }
@ -298,7 +298,7 @@ impl<I: Interner> CanonicalVarValues<I> {
pub fn is_identity_modulo_regions(&self) -> bool { pub fn is_identity_modulo_regions(&self) -> bool {
let mut var = ty::BoundVar::ZERO; let mut var = ty::BoundVar::ZERO;
for arg in self.var_values { for arg in self.var_values.iter() {
match arg.kind() { match arg.kind() {
ty::GenericArgKind::Lifetime(r) => { ty::GenericArgKind::Lifetime(r) => {
if matches!(r.kind(), ty::ReBound(ty::INNERMOST, br) if var == br.var()) { if matches!(r.kind(), ty::ReBound(ty::INNERMOST, br) if var == br.var()) {
@ -332,7 +332,7 @@ impl<I: Interner> CanonicalVarValues<I> {
// the identity response. // the identity response.
pub fn make_identity(tcx: I, infos: I::CanonicalVars) -> CanonicalVarValues<I> { pub fn make_identity(tcx: I, infos: I::CanonicalVars) -> CanonicalVarValues<I> {
CanonicalVarValues { CanonicalVarValues {
var_values: tcx.mk_args_from_iter(infos.into_iter().enumerate().map( var_values: tcx.mk_args_from_iter(infos.iter().enumerate().map(
|(i, info)| -> I::GenericArg { |(i, info)| -> I::GenericArg {
match info.kind { match info.kind {
CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => { CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => {
@ -371,10 +371,10 @@ impl<I: Interner> CanonicalVarValues<I> {
impl<'a, I: Interner> IntoIterator for &'a CanonicalVarValues<I> { impl<'a, I: Interner> IntoIterator for &'a CanonicalVarValues<I> {
type Item = I::GenericArg; type Item = I::GenericArg;
type IntoIter = <I::GenericArgs as IntoIterator>::IntoIter; type IntoIter = <I::GenericArgs as SliceLike>::IntoIter;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
self.var_values.into_iter() self.var_values.iter()
} }
} }
@ -382,6 +382,6 @@ impl<I: Interner> Index<ty::BoundVar> for CanonicalVarValues<I> {
type Output = I::GenericArg; type Output = I::GenericArg;
fn index(&self, value: ty::BoundVar) -> &I::GenericArg { fn index(&self, value: ty::BoundVar) -> &I::GenericArg {
&self.var_values[value.as_usize()] &self.var_values.as_slice()[value.as_usize()]
} }
} }

View file

@ -5,7 +5,6 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::hash::Hash; use std::hash::Hash;
use std::ops::Deref;
use rustc_ast_ir::Mutability; use rustc_ast_ir::Mutability;
@ -128,7 +127,7 @@ pub trait Ty<I: Interner<Ty = Self>>:
fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> { fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
match self.kind() { match self.kind() {
ty::FnPtr(sig) => sig, ty::FnPtr(sig) => sig,
ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, &args), ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args),
ty::Error(_) => { ty::Error(_) => {
// ignore errors (#54954) // ignore errors (#54954)
ty::Binder::dummy(ty::FnSig { ty::Binder::dummy(ty::FnSig {
@ -190,14 +189,7 @@ pub trait Ty<I: Interner<Ty = Self>>:
} }
pub trait Tys<I: Interner<Tys = Self>>: pub trait Tys<I: Interner<Tys = Self>>:
Copy Copy + Debug + Hash + Eq + SliceLike<Item = I::Ty> + TypeFoldable<I> + Default
+ Debug
+ Hash
+ Eq
+ IntoIterator<Item = I::Ty>
+ Deref<Target: Deref<Target = [I::Ty]>>
+ TypeFoldable<I>
+ Default
{ {
fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty); fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty);
} }
@ -362,14 +354,7 @@ pub trait Term<I: Interner<Term = Self>>:
} }
pub trait GenericArgs<I: Interner<GenericArgs = Self>>: pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
Copy Copy + Debug + Hash + Eq + SliceLike<Item = I::GenericArg> + Default + Relate<I>
+ Debug
+ Hash
+ Eq
+ IntoIterator<Item = I::GenericArg>
+ Deref<Target: Deref<Target = [I::GenericArg]>>
+ Default
+ Relate<I>
{ {
fn rebase_onto( fn rebase_onto(
self, self,
@ -561,12 +546,7 @@ pub trait DefId<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
} }
pub trait BoundExistentialPredicates<I: Interner>: pub trait BoundExistentialPredicates<I: Interner>:
Copy Copy + Debug + Hash + Eq + Relate<I> + SliceLike<Item = ty::Binder<I, ty::ExistentialPredicate<I>>>
+ Debug
+ Hash
+ Eq
+ Relate<I>
+ IntoIterator<Item = ty::Binder<I, ty::ExistentialPredicate<I>>>
{ {
fn principal_def_id(self) -> Option<I::DefId>; fn principal_def_id(self) -> Option<I::DefId>;
@ -578,3 +558,82 @@ pub trait BoundExistentialPredicates<I: Interner>:
self, self,
) -> impl IntoIterator<Item = ty::Binder<I, ty::ExistentialProjection<I>>>; ) -> impl IntoIterator<Item = ty::Binder<I, ty::ExistentialProjection<I>>>;
} }
pub trait SliceLike: Sized + Copy {
type Item: Copy;
type IntoIter: Iterator<Item = Self::Item>;
fn iter(self) -> Self::IntoIter;
fn as_slice(&self) -> &[Self::Item];
fn get(self, idx: usize) -> Option<Self::Item> {
self.as_slice().get(idx).copied()
}
fn len(self) -> usize {
self.as_slice().len()
}
fn is_empty(self) -> bool {
self.len() == 0
}
fn contains(self, t: &Self::Item) -> bool
where
Self::Item: PartialEq,
{
self.as_slice().contains(t)
}
fn to_vec(self) -> Vec<Self::Item> {
self.as_slice().to_vec()
}
fn last(self) -> Option<Self::Item> {
self.as_slice().last().copied()
}
fn split_last(&self) -> Option<(&Self::Item, &[Self::Item])> {
self.as_slice().split_last()
}
}
impl<'a, T: Copy> SliceLike for &'a [T] {
type Item = T;
type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>;
fn iter(self) -> Self::IntoIter {
self.iter().copied()
}
fn as_slice(&self) -> &[Self::Item] {
*self
}
}
impl<'a, T: Copy, const N: usize> SliceLike for &'a [T; N] {
type Item = T;
type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>;
fn iter(self) -> Self::IntoIter {
self.into_iter().copied()
}
fn as_slice(&self) -> &[Self::Item] {
*self
}
}
impl<'a, S: SliceLike> SliceLike for &'a S {
type Item = S::Item;
type IntoIter = S::IntoIter;
fn iter(self) -> Self::IntoIter {
(*self).iter()
}
fn as_slice(&self) -> &[Self::Item] {
(*self).as_slice()
}
}

View file

@ -34,16 +34,11 @@ pub trait Interner:
type LocalDefId: Copy + Debug + Hash + Eq + Into<Self::DefId> + TypeFoldable<Self>; type LocalDefId: Copy + Debug + Hash + Eq + Into<Self::DefId> + TypeFoldable<Self>;
type GenericArgs: GenericArgs<Self>; type GenericArgs: GenericArgs<Self>;
type GenericArgsSlice: Copy + Debug + Hash + Eq + Deref<Target = [Self::GenericArg]>; type GenericArgsSlice: Copy + Debug + Hash + Eq + SliceLike<Item = Self::GenericArg>;
type GenericArg: GenericArg<Self>; type GenericArg: GenericArg<Self>;
type Term: Term<Self>; type Term: Term<Self>;
type BoundVarKinds: Copy type BoundVarKinds: Copy + Debug + Hash + Eq + SliceLike<Item = Self::BoundVarKind> + Default;
+ Debug
+ Hash
+ Eq
+ Deref<Target: Deref<Target = [Self::BoundVarKind]>>
+ Default;
type BoundVarKind: Copy + Debug + Hash + Eq; type BoundVarKind: Copy + Debug + Hash + Eq;
type PredefinedOpaques: Copy type PredefinedOpaques: Copy
@ -63,7 +58,7 @@ pub trait Interner:
+ Default + Default
+ Eq + Eq
+ TypeVisitable<Self> + TypeVisitable<Self>
+ Deref<Target: Deref<Target = [Self::LocalDefId]>>; + SliceLike<Item = Self::LocalDefId>;
type CanonicalGoalEvaluationStepRef: Copy type CanonicalGoalEvaluationStepRef: Copy
+ Debug + Debug
+ Hash + Hash
@ -74,8 +69,7 @@ pub trait Interner:
+ Debug + Debug
+ Hash + Hash
+ Eq + Eq
+ IntoIterator<Item = ty::CanonicalVarInfo<Self>> + SliceLike<Item = ty::CanonicalVarInfo<Self>>
+ Deref<Target: Deref<Target = [ty::CanonicalVarInfo<Self>]>>
+ Default; + Default;
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars; fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
@ -138,11 +132,7 @@ pub trait Interner:
type GenericsOf: GenericsOf<Self>; type GenericsOf: GenericsOf<Self>;
fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf; fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
type VariancesOf: Copy type VariancesOf: Copy + Debug + SliceLike<Item = ty::Variance>;
+ Debug
+ Deref<Target = [ty::Variance]>
// FIXME: This is terrible!
+ IntoIterator<Item: Deref<Target = ty::Variance>>;
fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf; fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf;
fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder<Self, Self::Ty>; fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder<Self, Self::Ty>;

View file

@ -24,13 +24,13 @@ pub struct OpaqueTypeKey<I: Interner> {
impl<I: Interner> OpaqueTypeKey<I> { impl<I: Interner> OpaqueTypeKey<I> {
pub fn iter_captured_args(self, tcx: I) -> impl Iterator<Item = (usize, I::GenericArg)> { pub fn iter_captured_args(self, tcx: I) -> impl Iterator<Item = (usize, I::GenericArg)> {
let variances = tcx.variances_of(self.def_id.into()); let variances = tcx.variances_of(self.def_id.into());
std::iter::zip(self.args, variances.into_iter()).enumerate().filter_map(|(i, (arg, v))| { std::iter::zip(self.args.iter(), variances.iter()).enumerate().filter_map(
match (arg.kind(), *v) { |(i, (arg, v))| match (arg.kind(), v) {
(_, ty::Invariant) => Some((i, arg)), (_, ty::Invariant) => Some((i, arg)),
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => None, (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => None,
_ => panic!("unexpected opaque type arg variance"), _ => panic!("unexpected opaque type arg variance"),
} },
}) )
} }
pub fn fold_captured_lifetime_args( pub fn fold_captured_lifetime_args(
@ -41,7 +41,7 @@ impl<I: Interner> OpaqueTypeKey<I> {
let Self { def_id, args } = self; let Self { def_id, args } = self;
let variances = tcx.variances_of(def_id.into()); let variances = tcx.variances_of(def_id.into());
let args = let args =
std::iter::zip(args, variances.into_iter()).map(|(arg, v)| match (arg.kind(), *v) { std::iter::zip(args.iter(), variances.iter()).map(|(arg, v)| match (arg.kind(), v) {
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg, (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
(ty::GenericArgKind::Lifetime(lt), _) => f(lt).into(), (ty::GenericArgKind::Lifetime(lt), _) => f(lt).into(),
_ => arg, _ => arg,

View file

@ -85,7 +85,7 @@ impl<I: Interner> TraitRef<I> {
pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> { pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
let generics = interner.generics_of(trait_id); let generics = interner.generics_of(trait_id);
TraitRef::new(interner, trait_id, args.into_iter().take(generics.count())) TraitRef::new(interner, trait_id, args.iter().take(generics.count()))
} }
/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi` /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
@ -102,7 +102,7 @@ impl<I: Interner> TraitRef<I> {
TraitRef::new( TraitRef::new(
interner, interner,
self.def_id, self.def_id,
[self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)), [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
) )
} }
@ -320,7 +320,7 @@ impl<I: Interner> ExistentialTraitRef<I> {
ExistentialTraitRef { ExistentialTraitRef {
def_id: trait_ref.def_id, def_id: trait_ref.def_id,
args: interner.mk_args(&trait_ref.args[1..]), args: interner.mk_args(&trait_ref.args.as_slice()[1..]),
} }
} }
@ -332,11 +332,7 @@ impl<I: Interner> ExistentialTraitRef<I> {
// otherwise the escaping vars would be captured by the binder // otherwise the escaping vars would be captured by the binder
// debug_assert!(!self_ty.has_escaping_bound_vars()); // debug_assert!(!self_ty.has_escaping_bound_vars());
TraitRef::new( TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter()))
interner,
self.def_id,
[self_ty.into()].into_iter().chain(self.args.into_iter()),
)
} }
} }
@ -379,7 +375,7 @@ impl<I: Interner> ExistentialProjection<I> {
pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> { pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> {
let def_id = interner.parent(self.def_id); let def_id = interner.parent(self.def_id);
let args_count = interner.generics_of(def_id).count() - 1; let args_count = interner.generics_of(def_id).count() - 1;
let args = interner.mk_args(&self.args[..args_count]); let args = interner.mk_args(&self.args.as_slice()[..args_count]);
ExistentialTraitRef { def_id, args } ExistentialTraitRef { def_id, args }
} }
@ -391,7 +387,7 @@ impl<I: Interner> ExistentialProjection<I> {
projection_term: AliasTerm::new( projection_term: AliasTerm::new(
interner, interner,
self.def_id, self.def_id,
[self_ty.into()].into_iter().chain(self.args), [self_ty.into()].iter().chain(self.args.iter()),
), ),
term: self.term, term: self.term,
} }
@ -403,7 +399,7 @@ impl<I: Interner> ExistentialProjection<I> {
Self { Self {
def_id: projection_predicate.projection_term.def_id, def_id: projection_predicate.projection_term.def_id,
args: interner.mk_args(&projection_predicate.projection_term.args[1..]), args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]),
term: projection_predicate.term, term: projection_predicate.term,
} }
} }
@ -578,7 +574,7 @@ impl<I: Interner> AliasTerm<I> {
AliasTerm::new( AliasTerm::new(
interner, interner,
self.def_id, self.def_id,
[self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)), [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
) )
} }

View file

@ -82,7 +82,7 @@ pub trait TypeRelation<I: Interner>: Sized {
let tcx = self.tcx(); let tcx = self.tcx();
let opt_variances = tcx.variances_of(item_def_id); let opt_variances = tcx.variances_of(item_def_id);
relate_args_with_variances(self, item_def_id, &opt_variances, a_arg, b_arg, true) relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, true)
} }
/// Switch variance for the purpose of relating `a` and `b`. /// Switch variance for the purpose of relating `a` and `b`.
@ -128,7 +128,7 @@ pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>(
a_arg: I::GenericArgs, a_arg: I::GenericArgs,
b_arg: I::GenericArgs, b_arg: I::GenericArgs,
) -> RelateResult<I, I::GenericArgs> { ) -> RelateResult<I, I::GenericArgs> {
relation.tcx().mk_args_from_iter(iter::zip(a_arg, b_arg).map(|(a, b)| { relation.tcx().mk_args_from_iter(iter::zip(a_arg.iter(), b_arg.iter()).map(|(a, b)| {
relation.relate_with_variance(ty::Invariant, VarianceDiagInfo::default(), a, b) relation.relate_with_variance(ty::Invariant, VarianceDiagInfo::default(), a, b)
})) }))
} }
@ -136,7 +136,7 @@ pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>(
pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>( pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>(
relation: &mut R, relation: &mut R,
ty_def_id: I::DefId, ty_def_id: I::DefId,
variances: &[ty::Variance], variances: I::VariancesOf,
a_arg: I::GenericArgs, a_arg: I::GenericArgs,
b_arg: I::GenericArgs, b_arg: I::GenericArgs,
fetch_ty_for_diag: bool, fetch_ty_for_diag: bool,
@ -144,11 +144,11 @@ pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>(
let tcx = relation.tcx(); let tcx = relation.tcx();
let mut cached_ty = None; let mut cached_ty = None;
let params = iter::zip(a_arg, b_arg).enumerate().map(|(i, (a, b))| { let params = iter::zip(a_arg.iter(), b_arg.iter()).enumerate().map(|(i, (a, b))| {
let variance = variances[i]; let variance = variances.get(i).unwrap();
let variance_info = if variance == ty::Invariant && fetch_ty_for_diag { let variance_info = if variance == ty::Invariant && fetch_ty_for_diag {
let ty = let ty =
*cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, &a_arg)); *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, a_arg));
VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() } VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
} else { } else {
VarianceDiagInfo::default() VarianceDiagInfo::default()
@ -249,7 +249,7 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> {
ty::Opaque => relate_args_with_variances( ty::Opaque => relate_args_with_variances(
relation, relation,
a.def_id, a.def_id,
&relation.tcx().variances_of(a.def_id), relation.tcx().variances_of(a.def_id),
a.args, a.args,
b.args, b.args,
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
@ -280,7 +280,7 @@ impl<I: Interner> Relate<I> for ty::AliasTerm<I> {
ty::AliasTermKind::OpaqueTy => relate_args_with_variances( ty::AliasTermKind::OpaqueTy => relate_args_with_variances(
relation, relation,
a.def_id, a.def_id,
&relation.tcx().variances_of(a.def_id), relation.tcx().variances_of(a.def_id),
a.args, a.args,
b.args, b.args,
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
@ -525,7 +525,7 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
if as_.len() == bs.len() { if as_.len() == bs.len() {
Ok(Ty::new_tup_from_iter( Ok(Ty::new_tup_from_iter(
tcx, tcx,
iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)), iter::zip(as_.iter(), bs.iter()).map(|(a, b)| relation.relate(a, b)),
)?) )?)
} else if !(as_.is_empty() || bs.is_empty()) { } else if !(as_.is_empty() || bs.is_empty()) {
Err(TypeError::TupleSize(ExpectedFound::new(true, as_.len(), bs.len()))) Err(TypeError::TupleSize(ExpectedFound::new(true, as_.len(), bs.len())))
@ -607,8 +607,8 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
// be stabilized. // be stabilized.
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => { (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
let a_ty = tcx.type_of(au.def).instantiate(tcx, &au.args); let a_ty = tcx.type_of(au.def).instantiate(tcx, au.args);
let b_ty = tcx.type_of(bu.def).instantiate(tcx, &bu.args); let b_ty = tcx.type_of(bu.def).instantiate(tcx, bu.args);
assert_eq!(a_ty, b_ty); assert_eq!(a_ty, b_ty);
} }

View file

@ -388,7 +388,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
Tuple(t) => { Tuple(t) => {
write!(f, "(")?; write!(f, "(")?;
let mut count = 0; let mut count = 0;
for ty in *t { for ty in t.iter() {
if count > 0 { if count > 0 {
write!(f, ", ")?; write!(f, ", ")?;
} }
@ -496,7 +496,7 @@ impl<I: Interner> AliasTy<I> {
AliasTy::new( AliasTy::new(
interner, interner,
self.def_id, self.def_id,
[self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)), [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
) )
} }
@ -544,7 +544,7 @@ impl<I: Interner> AliasTy<I> {
interner: I, interner: I,
) -> I::GenericArgs { ) -> I::GenericArgs {
debug_assert_eq!(self.kind(interner), AliasTyKind::Inherent); debug_assert_eq!(self.kind(interner), AliasTyKind::Inherent);
interner.mk_args_from_iter(impl_args.into_iter().chain(self.args.into_iter().skip(1))) interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
} }
} }

View file

@ -138,7 +138,7 @@ impl<I: Interner> ClosureArgs<I> {
/// for the closure parent, alongside additional closure-specific components. /// for the closure parent, alongside additional closure-specific components.
pub fn new(tcx: I, parts: ClosureArgsParts<I>) -> ClosureArgs<I> { pub fn new(tcx: I, parts: ClosureArgsParts<I>) -> ClosureArgs<I> {
ClosureArgs { ClosureArgs {
args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([ args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([
parts.closure_kind_ty.into(), parts.closure_kind_ty.into(),
parts.closure_sig_as_fn_ptr_ty.into(), parts.closure_sig_as_fn_ptr_ty.into(),
parts.tupled_upvars_ty.into(), parts.tupled_upvars_ty.into(),
@ -260,7 +260,7 @@ pub struct CoroutineClosureArgsParts<I: Interner> {
impl<I: Interner> CoroutineClosureArgs<I> { impl<I: Interner> CoroutineClosureArgs<I> {
pub fn new(tcx: I, parts: CoroutineClosureArgsParts<I>) -> CoroutineClosureArgs<I> { pub fn new(tcx: I, parts: CoroutineClosureArgsParts<I>) -> CoroutineClosureArgs<I> {
CoroutineClosureArgs { CoroutineClosureArgs {
args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([ args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([
parts.closure_kind_ty.into(), parts.closure_kind_ty.into(),
parts.signature_parts_ty.into(), parts.signature_parts_ty.into(),
parts.tupled_upvars_ty.into(), parts.tupled_upvars_ty.into(),
@ -312,7 +312,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
let [resume_ty, tupled_inputs_ty] = *sig.inputs() else { let [resume_ty, tupled_inputs_ty] = *sig.inputs() else {
panic!(); panic!();
}; };
let [yield_ty, return_ty] = **sig.output().tuple_fields() else { panic!() }; let [yield_ty, return_ty] = *sig.output().tuple_fields().as_slice() else { panic!() };
CoroutineClosureSignature { CoroutineClosureSignature {
interior, interior,
tupled_inputs_ty, tupled_inputs_ty,
@ -496,16 +496,16 @@ impl<I: Interner> CoroutineClosureSignature<I> {
tcx, tcx,
tupled_inputs_ty tupled_inputs_ty
.tuple_fields() .tuple_fields()
.into_iter() .iter()
.chain(coroutine_captures_by_ref_ty.tuple_fields()), .chain(coroutine_captures_by_ref_ty.tuple_fields().iter()),
) )
} }
ty::ClosureKind::FnOnce => Ty::new_tup_from_iter( ty::ClosureKind::FnOnce => Ty::new_tup_from_iter(
tcx, tcx,
tupled_inputs_ty tupled_inputs_ty
.tuple_fields() .tuple_fields()
.into_iter() .iter()
.chain(closure_tupled_upvars_ty.tuple_fields()), .chain(closure_tupled_upvars_ty.tuple_fields().iter()),
), ),
} }
} }
@ -617,7 +617,7 @@ impl<I: Interner> CoroutineArgs<I> {
/// for the coroutine parent, alongside additional coroutine-specific components. /// for the coroutine parent, alongside additional coroutine-specific components.
pub fn new(tcx: I, parts: CoroutineArgsParts<I>) -> CoroutineArgs<I> { pub fn new(tcx: I, parts: CoroutineArgsParts<I>) -> CoroutineArgs<I> {
CoroutineArgs { CoroutineArgs {
args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([ args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([
parts.kind_ty.into(), parts.kind_ty.into(),
parts.resume_ty.into(), parts.resume_ty.into(),
parts.yield_ty.into(), parts.yield_ty.into(),

View file

@ -267,7 +267,7 @@ fn needless_borrow_count<'tcx>(
return false; return false;
} }
let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty); let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty[..]);
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate); let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
let infcx = cx.tcx.infer_ctxt().build(); let infcx = cx.tcx.infer_ctxt().build();
infcx.predicate_must_hold_modulo_regions(&obligation) infcx.predicate_must_hold_modulo_regions(&obligation)