Skip to content

Commit 21d95fb

Browse files
More compare_impl_item simplifications
1 parent 73a37a1 commit 21d95fb

File tree

3 files changed

+95
-76
lines changed

3 files changed

+95
-76
lines changed

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+52-73
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,13 @@ mod refine;
4343
/// - `impl_m`: type of the method we are checking
4444
/// - `trait_m`: the method in the trait
4545
/// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation
46+
#[instrument(level = "debug", skip(tcx))]
4647
pub(super) fn compare_impl_method<'tcx>(
4748
tcx: TyCtxt<'tcx>,
4849
impl_m: ty::AssocItem,
4950
trait_m: ty::AssocItem,
5051
impl_trait_ref: ty::TraitRef<'tcx>,
5152
) {
52-
debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref);
53-
5453
let _: Result<_, ErrorGuaranteed> = try {
5554
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?;
5655
compare_method_predicate_entailment(tcx, impl_m, trait_m, impl_trait_ref)?;
@@ -167,8 +166,6 @@ fn compare_method_predicate_entailment<'tcx>(
167166
trait_m: ty::AssocItem,
168167
impl_trait_ref: ty::TraitRef<'tcx>,
169168
) -> Result<(), ErrorGuaranteed> {
170-
let trait_to_impl_args = impl_trait_ref.args;
171-
172169
// This node-id should be used for the `body_id` field on each
173170
// `ObligationCause` (and the `FnCtxt`).
174171
//
@@ -183,13 +180,13 @@ fn compare_method_predicate_entailment<'tcx>(
183180
kind: impl_m.kind,
184181
});
185182

186-
// Create mapping from impl to placeholder.
187-
let impl_to_placeholder_args = GenericArgs::identity_for_item(tcx, impl_m.def_id);
188-
189-
// 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);
183+
// Create mapping from trait method to impl method.
184+
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto(
185+
tcx,
186+
impl_m.container_id(tcx),
187+
impl_trait_ref.args,
188+
);
189+
debug!(?trait_to_impl_args);
193190

194191
let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
195192
let trait_m_predicates = tcx.predicates_of(trait_m.def_id);
@@ -204,28 +201,22 @@ fn compare_method_predicate_entailment<'tcx>(
204201
let impl_predicates = tcx.predicates_of(impl_m_predicates.parent.unwrap());
205202
let mut hybrid_preds = impl_predicates.instantiate_identity(tcx).predicates;
206203
hybrid_preds.extend(
207-
trait_m_predicates
208-
.instantiate_own(tcx, trait_to_placeholder_args)
209-
.map(|(predicate, _)| predicate),
204+
trait_m_predicates.instantiate_own(tcx, trait_to_impl_args).map(|(predicate, _)| predicate),
210205
);
211206

212-
// Construct trait parameter environment and then shift it into the placeholder viewpoint.
213-
// The key step here is to update the caller_bounds's predicates to be
214-
// the new hybrid bounds we computed.
215207
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
216208
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
217209
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
210+
debug!(caller_bounds=?param_env.caller_bounds());
218211

219212
let infcx = &tcx.infer_ctxt().build();
220213
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
221214

222-
debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds());
223-
224215
// Create obligations for each predicate declared by the impl
225216
// definition in the context of the hybrid param-env. This makes
226217
// sure that the impl's method's where clauses are not more
227218
// 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);
219+
let impl_m_own_bounds = impl_m_predicates.instantiate_own_identity();
229220
for (predicate, span) in impl_m_own_bounds {
230221
let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
231222
let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
@@ -252,7 +243,6 @@ fn compare_method_predicate_entailment<'tcx>(
252243
// any associated types appearing in the fn arguments or return
253244
// type.
254245

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

258248
let unnormalized_impl_sig = infcx.instantiate_binder_with_fresh_vars(
@@ -263,9 +253,9 @@ fn compare_method_predicate_entailment<'tcx>(
263253

264254
let norm_cause = ObligationCause::misc(impl_m_span, impl_m_def_id);
265255
let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig);
266-
debug!("compare_impl_method: impl_fty={:?}", impl_sig);
256+
debug!(?impl_sig);
267257

268-
let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_placeholder_args);
258+
let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args);
269259
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig);
270260

271261
// Next, add all inputs and output as well-formed tys. Importantly,
@@ -276,9 +266,7 @@ fn compare_method_predicate_entailment<'tcx>(
276266
// We also have to add the normalized trait signature
277267
// as we don't normalize during implied bounds computation.
278268
wf_tys.extend(trait_sig.inputs_and_output.iter());
279-
let trait_fty = Ty::new_fn_ptr(tcx, ty::Binder::dummy(trait_sig));
280-
281-
debug!("compare_impl_method: trait_fty={:?}", trait_fty);
269+
debug!(?trait_sig);
282270

283271
// FIXME: We'd want to keep more accurate spans than "the method signature" when
284272
// processing the comparison between the trait and impl fn, but we sadly lose them
@@ -451,8 +439,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
451439
// just so we don't ICE during instantiation later.
452440
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
453441

454-
let trait_to_impl_args = impl_trait_ref.args;
455-
456442
let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id);
457443
let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
458444
let cause =
@@ -462,18 +448,18 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
462448
kind: impl_m.kind,
463449
});
464450

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);
451+
// Create mapping from trait to impl (i.e. impl trait header + impl method identity args).
452+
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto(
453+
tcx,
454+
impl_m.container_id(tcx),
455+
impl_trait_ref.args,
456+
);
471457

472458
let hybrid_preds = tcx
473459
.predicates_of(impl_m.container_id(tcx))
474460
.instantiate_identity(tcx)
475461
.into_iter()
476-
.chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_placeholder_args))
462+
.chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args))
477463
.map(|(clause, _)| clause);
478464
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing);
479465
let param_env = traits::normalize_param_env_or_error(
@@ -507,7 +493,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
507493
.instantiate_binder_with_fresh_vars(
508494
return_span,
509495
infer::HigherRankedType,
510-
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_placeholder_args),
496+
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args),
511497
)
512498
.fold_with(&mut collector);
513499

@@ -701,7 +687,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
701687
// Also, we only need to account for a difference in trait and impl args,
702688
// since we previously enforce that the trait method and impl method have the
703689
// same generics.
704-
let num_trait_args = trait_to_impl_args.len();
690+
let num_trait_args = impl_trait_ref.args.len();
705691
let num_impl_args = tcx.generics_of(impl_m.container_id(tcx)).own_params.len();
706692
let ty = match ty.try_fold_with(&mut RemapHiddenTyRegions {
707693
tcx,
@@ -1037,12 +1023,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
10371023
let trait_generics = tcx.generics_of(trait_m.def_id);
10381024
let trait_params = trait_generics.own_counts().lifetimes;
10391025

1040-
debug!(
1041-
"check_region_bounds_on_impl_item: \
1042-
trait_generics={:?} \
1043-
impl_generics={:?}",
1044-
trait_generics, impl_generics
1045-
);
1026+
debug!(?trait_generics, ?impl_generics);
10461027

10471028
// Must have same number of early-bound lifetime parameters.
10481029
// Unfortunately, if the user screws up the bounds, then this
@@ -1706,8 +1687,7 @@ pub(super) fn compare_impl_const_raw(
17061687
let trait_const_item = tcx.associated_item(trait_const_item_def);
17071688
let impl_trait_ref =
17081689
tcx.impl_trait_ref(impl_const_item.container_id(tcx)).unwrap().instantiate_identity();
1709-
1710-
debug!("compare_impl_const(impl_trait_ref={:?})", impl_trait_ref);
1690+
debug!(?impl_trait_ref);
17111691

17121692
compare_number_of_generics(tcx, impl_const_item, trait_const_item, false)?;
17131693
compare_generic_param_kinds(tcx, impl_const_item, trait_const_item, false)?;
@@ -1718,6 +1698,7 @@ pub(super) fn compare_impl_const_raw(
17181698
/// The equivalent of [compare_method_predicate_entailment], but for associated constants
17191699
/// instead of associated functions.
17201700
// FIXME(generic_const_items): If possible extract the common parts of `compare_{type,const}_predicate_entailment`.
1701+
#[instrument(level = "debug", skip(tcx))]
17211702
fn compare_const_predicate_entailment<'tcx>(
17221703
tcx: TyCtxt<'tcx>,
17231704
impl_ct: ty::AssocItem,
@@ -1732,13 +1713,14 @@ fn compare_const_predicate_entailment<'tcx>(
17321713
// because we shouldn't really have to deal with lifetimes or
17331714
// predicates. In fact some of this should probably be put into
17341715
// 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);
1716+
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_ct.def_id).rebase_onto(
1717+
tcx,
1718+
impl_ct.container_id(tcx),
1719+
impl_trait_ref.args,
1720+
);
17381721

17391722
// Create a parameter environment that represents the implementation's
1740-
// method.
1741-
// Compute placeholder form of impl and trait const tys.
1723+
// associated const.
17421724
let impl_ty = tcx.type_of(impl_ct_def_id).instantiate_identity();
17431725

17441726
let trait_ty = tcx.type_of(trait_ct.def_id).instantiate(tcx, trait_to_impl_args);
@@ -1772,7 +1754,7 @@ fn compare_const_predicate_entailment<'tcx>(
17721754
let infcx = tcx.infer_ctxt().build();
17731755
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
17741756

1775-
let impl_ct_own_bounds = impl_ct_predicates.instantiate_own(tcx, impl_args);
1757+
let impl_ct_own_bounds = impl_ct_predicates.instantiate_own_identity();
17761758
for (predicate, span) in impl_ct_own_bounds {
17771759
let cause = ObligationCause::misc(span, impl_ct_def_id);
17781760
let predicate = ocx.normalize(&cause, param_env, predicate);
@@ -1783,20 +1765,15 @@ fn compare_const_predicate_entailment<'tcx>(
17831765

17841766
// There is no "body" here, so just pass dummy id.
17851767
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
1786-
1787-
debug!("compare_const_impl: impl_ty={:?}", impl_ty);
1768+
debug!(?impl_ty);
17881769

17891770
let trait_ty = ocx.normalize(&cause, param_env, trait_ty);
1790-
1791-
debug!("compare_const_impl: trait_ty={:?}", trait_ty);
1771+
debug!(?trait_ty);
17921772

17931773
let err = ocx.sup(&cause, param_env, trait_ty, impl_ty);
17941774

17951775
if let Err(terr) = err {
1796-
debug!(
1797-
"checking associated const for compatibility: impl ty {:?}, trait ty {:?}",
1798-
impl_ty, trait_ty
1799-
);
1776+
debug!(?impl_ty, ?trait_ty);
18001777

18011778
// Locate the Span containing just the type of the offending impl
18021779
let (ty, _) = tcx.hir().expect_impl_item(impl_ct_def_id).expect_const();
@@ -1841,14 +1818,13 @@ fn compare_const_predicate_entailment<'tcx>(
18411818
ocx.resolve_regions_and_report_errors(impl_ct_def_id, &outlives_env)
18421819
}
18431820

1821+
#[instrument(level = "debug", skip(tcx))]
18441822
pub(super) fn compare_impl_ty<'tcx>(
18451823
tcx: TyCtxt<'tcx>,
18461824
impl_ty: ty::AssocItem,
18471825
trait_ty: ty::AssocItem,
18481826
impl_trait_ref: ty::TraitRef<'tcx>,
18491827
) {
1850-
debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref);
1851-
18521828
let _: Result<(), ErrorGuaranteed> = try {
18531829
compare_number_of_generics(tcx, impl_ty, trait_ty, false)?;
18541830
compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?;
@@ -1860,20 +1836,23 @@ pub(super) fn compare_impl_ty<'tcx>(
18601836

18611837
/// The equivalent of [compare_method_predicate_entailment], but for associated types
18621838
/// instead of associated functions.
1839+
#[instrument(level = "debug", skip(tcx))]
18631840
fn compare_type_predicate_entailment<'tcx>(
18641841
tcx: TyCtxt<'tcx>,
18651842
impl_ty: ty::AssocItem,
18661843
trait_ty: ty::AssocItem,
18671844
impl_trait_ref: ty::TraitRef<'tcx>,
18681845
) -> 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);
1846+
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id).rebase_onto(
1847+
tcx,
1848+
impl_ty.container_id(tcx),
1849+
impl_trait_ref.args,
1850+
);
18721851

18731852
let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id);
18741853
let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
18751854

1876-
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_args);
1855+
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own_identity();
18771856
if impl_ty_own_bounds.len() == 0 {
18781857
// Nothing to check.
18791858
return Ok(());
@@ -1883,7 +1862,7 @@ fn compare_type_predicate_entailment<'tcx>(
18831862
// `ObligationCause` (and the `FnCtxt`). This is what
18841863
// `regionck_item` expects.
18851864
let impl_ty_def_id = impl_ty.def_id.expect_local();
1886-
debug!("compare_type_predicate_entailment: trait_to_impl_args={:?}", trait_to_impl_args);
1865+
debug!(?trait_to_impl_args);
18871866

18881867
// The predicates declared by the impl definition, the trait and the
18891868
// associated type in the trait are assumed.
@@ -1894,18 +1873,18 @@ fn compare_type_predicate_entailment<'tcx>(
18941873
.instantiate_own(tcx, trait_to_impl_args)
18951874
.map(|(predicate, _)| predicate),
18961875
);
1897-
1898-
debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds);
1876+
debug!(?hybrid_preds);
18991877

19001878
let impl_ty_span = tcx.def_span(impl_ty_def_id);
19011879
let normalize_cause = ObligationCause::misc(impl_ty_span, impl_ty_def_id);
1880+
19021881
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
19031882
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
1883+
debug!(caller_bounds=?param_env.caller_bounds());
1884+
19041885
let infcx = tcx.infer_ctxt().build();
19051886
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
19061887

1907-
debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds());
1908-
19091888
for (predicate, span) in impl_ty_own_bounds {
19101889
let cause = ObligationCause::misc(span, impl_ty_def_id);
19111890
let predicate = ocx.normalize(&cause, param_env, predicate);
@@ -2005,11 +1984,11 @@ pub(super) fn check_type_bounds<'tcx>(
20051984
.explicit_item_bounds(trait_ty.def_id)
20061985
.iter_instantiated_copied(tcx, rebased_args)
20071986
.map(|(concrete_ty_bound, span)| {
2008-
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
1987+
debug!(?concrete_ty_bound);
20091988
traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
20101989
})
20111990
.collect();
2012-
debug!("check_type_bounds: item_bounds={:?}", obligations);
1991+
debug!(item_bounds=?obligations);
20131992

20141993
// Normalize predicates with the assumption that the GAT may always normalize
20151994
// to its definition type. This should be the param-env we use to *prove* the
@@ -2028,7 +2007,7 @@ pub(super) fn check_type_bounds<'tcx>(
20282007
} else {
20292008
ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate)
20302009
};
2031-
debug!("compare_projection_bounds: normalized predicate = {:?}", normalized_predicate);
2010+
debug!(?normalized_predicate);
20322011
obligation.predicate = normalized_predicate;
20332012

20342013
ocx.register_obligation(obligation);

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

0 commit comments

Comments
 (0)