Skip to content

Commit a844b11

Browse files
More compare_impl_item simplifications
1 parent 9a370c4 commit a844b11

File tree

4 files changed

+75
-38
lines changed

4 files changed

+75
-38
lines changed

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+29-33
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,6 @@ fn compare_method_predicate_entailment<'tcx>(
167167
trait_m: ty::AssocItem,
168168
impl_trait_ref: ty::TraitRef<'tcx>,
169169
) -> Result<(), ErrorGuaranteed> {
170-
let trait_to_impl_args = impl_trait_ref.args;
171-
172170
// This node-id should be used for the `body_id` field on each
173171
// `ObligationCause` (and the `FnCtxt`).
174172
//
@@ -183,13 +181,13 @@ fn compare_method_predicate_entailment<'tcx>(
183181
kind: impl_m.kind,
184182
});
185183

186-
// Create mapping from impl to placeholder.
187-
let impl_to_placeholder_args = GenericArgs::identity_for_item(tcx, impl_m.def_id);
188-
189184
// Create mapping from trait to placeholder.
190-
let trait_to_placeholder_args =
191-
impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args);
192-
debug!("compare_impl_method: trait_to_placeholder_args={:?}", trait_to_placeholder_args);
185+
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto(
186+
tcx,
187+
impl_m.container_id(tcx),
188+
impl_trait_ref.args,
189+
);
190+
debug!("compare_impl_method: trait_to_placeholder_args={:?}", trait_to_impl_args);
193191

194192
let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
195193
let trait_m_predicates = tcx.predicates_of(trait_m.def_id);
@@ -204,9 +202,7 @@ fn compare_method_predicate_entailment<'tcx>(
204202
let impl_predicates = tcx.predicates_of(impl_m_predicates.parent.unwrap());
205203
let mut hybrid_preds = impl_predicates.instantiate_identity(tcx).predicates;
206204
hybrid_preds.extend(
207-
trait_m_predicates
208-
.instantiate_own(tcx, trait_to_placeholder_args)
209-
.map(|(predicate, _)| predicate),
205+
trait_m_predicates.instantiate_own(tcx, trait_to_impl_args).map(|(predicate, _)| predicate),
210206
);
211207

212208
// Construct trait parameter environment and then shift it into the placeholder viewpoint.
@@ -225,7 +221,7 @@ fn compare_method_predicate_entailment<'tcx>(
225221
// definition in the context of the hybrid param-env. This makes
226222
// sure that the impl's method's where clauses are not more
227223
// restrictive than the trait's method (and the impl itself).
228-
let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_args);
224+
let impl_m_own_bounds = impl_m_predicates.instantiate_own_identity();
229225
for (predicate, span) in impl_m_own_bounds {
230226
let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
231227
let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
@@ -252,7 +248,6 @@ fn compare_method_predicate_entailment<'tcx>(
252248
// any associated types appearing in the fn arguments or return
253249
// type.
254250

255-
// Compute placeholder form of impl and trait method tys.
256251
let mut wf_tys = FxIndexSet::default();
257252

258253
let unnormalized_impl_sig = infcx.instantiate_binder_with_fresh_vars(
@@ -265,7 +260,7 @@ fn compare_method_predicate_entailment<'tcx>(
265260
let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig);
266261
debug!("compare_impl_method: impl_fty={:?}", impl_sig);
267262

268-
let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_placeholder_args);
263+
let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args);
269264
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig);
270265

271266
// Next, add all inputs and output as well-formed tys. Importantly,
@@ -451,8 +446,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
451446
// just so we don't ICE during instantiation later.
452447
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
453448

454-
let trait_to_impl_args = impl_trait_ref.args;
455-
456449
let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id);
457450
let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
458451
let cause =
@@ -462,18 +455,18 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
462455
kind: impl_m.kind,
463456
});
464457

465-
// Create mapping from impl to placeholder.
466-
let impl_to_placeholder_args = GenericArgs::identity_for_item(tcx, impl_m.def_id);
467-
468-
// Create mapping from trait to placeholder.
469-
let trait_to_placeholder_args =
470-
impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args);
458+
// Create mapping from trait to impl (i.e. impl trait header + impl method identity args).
459+
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto(
460+
tcx,
461+
impl_m.container_id(tcx),
462+
impl_trait_ref.args,
463+
);
471464

472465
let hybrid_preds = tcx
473466
.predicates_of(impl_m.container_id(tcx))
474467
.instantiate_identity(tcx)
475468
.into_iter()
476-
.chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_placeholder_args))
469+
.chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args))
477470
.map(|(clause, _)| clause);
478471
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing);
479472
let param_env = traits::normalize_param_env_or_error(
@@ -507,7 +500,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
507500
.instantiate_binder_with_fresh_vars(
508501
return_span,
509502
infer::HigherRankedType,
510-
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_placeholder_args),
503+
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args),
511504
)
512505
.fold_with(&mut collector);
513506

@@ -1732,13 +1725,14 @@ fn compare_const_predicate_entailment<'tcx>(
17321725
// because we shouldn't really have to deal with lifetimes or
17331726
// predicates. In fact some of this should probably be put into
17341727
// shared functions because of DRY violations...
1735-
let impl_args = GenericArgs::identity_for_item(tcx, impl_ct.def_id);
1736-
let trait_to_impl_args =
1737-
impl_args.rebase_onto(tcx, impl_ct.container_id(tcx), impl_trait_ref.args);
1728+
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_ct.def_id).rebase_onto(
1729+
tcx,
1730+
impl_ct.container_id(tcx),
1731+
impl_trait_ref.args,
1732+
);
17381733

17391734
// Create a parameter environment that represents the implementation's
17401735
// method.
1741-
// Compute placeholder form of impl and trait const tys.
17421736
let impl_ty = tcx.type_of(impl_ct_def_id).instantiate_identity();
17431737

17441738
let trait_ty = tcx.type_of(trait_ct.def_id).instantiate(tcx, trait_to_impl_args);
@@ -1772,7 +1766,7 @@ fn compare_const_predicate_entailment<'tcx>(
17721766
let infcx = tcx.infer_ctxt().build();
17731767
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
17741768

1775-
let impl_ct_own_bounds = impl_ct_predicates.instantiate_own(tcx, impl_args);
1769+
let impl_ct_own_bounds = impl_ct_predicates.instantiate_own_identity();
17761770
for (predicate, span) in impl_ct_own_bounds {
17771771
let cause = ObligationCause::misc(span, impl_ct_def_id);
17781772
let predicate = ocx.normalize(&cause, param_env, predicate);
@@ -1866,14 +1860,16 @@ fn compare_type_predicate_entailment<'tcx>(
18661860
trait_ty: ty::AssocItem,
18671861
impl_trait_ref: ty::TraitRef<'tcx>,
18681862
) -> Result<(), ErrorGuaranteed> {
1869-
let impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id);
1870-
let trait_to_impl_args =
1871-
impl_args.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.args);
1863+
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id).rebase_onto(
1864+
tcx,
1865+
impl_ty.container_id(tcx),
1866+
impl_trait_ref.args,
1867+
);
18721868

18731869
let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id);
18741870
let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
18751871

1876-
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_args);
1872+
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own_identity();
18771873
if impl_ty_own_bounds.len() == 0 {
18781874
// Nothing to check.
18791875
return Ok(());

compiler/rustc_middle/src/ty/generics.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,9 @@ impl<'tcx> GenericPredicates<'tcx> {
395395
EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args)
396396
}
397397

398-
pub fn instantiate_own_identity(self) -> impl Iterator<Item = (Clause<'tcx>, Span)> {
398+
pub fn instantiate_own_identity(
399+
self,
400+
) -> impl Iterator<Item = (Clause<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator {
399401
EarlyBinder::bind(self.predicates).iter_identity_copied()
400402
}
401403

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,9 @@ where
166166
// inference variables. This tends to only happen if we encounter a lot of
167167
// ambiguous alias types which get replaced with fresh inference variables
168168
// during generalization. This prevents a hang in nalgebra.
169-
let num_non_region_vars = canonical.variables.iter().filter(|c| !c.is_region()).count();
170-
if num_non_region_vars > self.cx().recursion_limit() {
169+
let num_non_region_vars =
170+
canonical.variables.iter().filter(|c| !c.is_region() && c.is_existential()).count();
171+
if num_non_region_vars > self.cx().recursion_limit() * 10 {
171172
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow {
172173
suggest_increasing_limit: true,
173174
}));

compiler/rustc_type_ir/src/binder.rs

+40-2
Original file line numberDiff line numberDiff line change
@@ -496,8 +496,8 @@ where
496496

497497
/// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity),
498498
/// but on an iterator of values that deref to a `TypeFoldable`.
499-
pub fn iter_identity_copied(self) -> impl Iterator<Item = <Iter::Item as Deref>::Target> {
500-
self.value.into_iter().map(|v| *v)
499+
pub fn iter_identity_copied(self) -> IterIdentityCopied<Iter> {
500+
IterIdentityCopied { it: self.value.into_iter() }
501501
}
502502
}
503503

@@ -546,6 +546,44 @@ where
546546
{
547547
}
548548

549+
pub struct IterIdentityCopied<Iter: IntoIterator> {
550+
it: Iter::IntoIter,
551+
}
552+
553+
impl<Iter: IntoIterator> Iterator for IterIdentityCopied<Iter>
554+
where
555+
Iter::Item: Deref,
556+
<Iter::Item as Deref>::Target: Copy,
557+
{
558+
type Item = <Iter::Item as Deref>::Target;
559+
560+
fn next(&mut self) -> Option<Self::Item> {
561+
self.it.next().map(|i| *i)
562+
}
563+
564+
fn size_hint(&self) -> (usize, Option<usize>) {
565+
self.it.size_hint()
566+
}
567+
}
568+
569+
impl<Iter: IntoIterator> DoubleEndedIterator for IterIdentityCopied<Iter>
570+
where
571+
Iter::IntoIter: DoubleEndedIterator,
572+
Iter::Item: Deref,
573+
<Iter::Item as Deref>::Target: Copy,
574+
{
575+
fn next_back(&mut self) -> Option<Self::Item> {
576+
self.it.next_back().map(|i| *i)
577+
}
578+
}
579+
580+
impl<Iter: IntoIterator> ExactSizeIterator for IterIdentityCopied<Iter>
581+
where
582+
Iter::IntoIter: ExactSizeIterator,
583+
Iter::Item: Deref,
584+
<Iter::Item as Deref>::Target: Copy,
585+
{
586+
}
549587
pub struct EarlyBinderIter<I, T> {
550588
t: T,
551589
_tcx: PhantomData<I>,

0 commit comments

Comments
 (0)