Skip to content

Commit 4b190dc

Browse files
committed
Apply EarlyBinder only to TraitRef in ImplTraitHeader
1 parent bdde2a8 commit 4b190dc

File tree

22 files changed

+74
-82
lines changed

22 files changed

+74
-82
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1612,10 +1612,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16121612
.any(|impl_def_id| {
16131613
let impl_header = tcx.impl_trait_header(impl_def_id);
16141614
impl_header.is_some_and(|header| {
1615-
let header = header.instantiate(
1615+
let trait_ref = header.trait_ref.instantiate(
16161616
tcx,
16171617
infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
16181618
);
1619+
16191620
let value = tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased);
16201621
// FIXME: Don't bother dealing with non-lifetime binders here...
16211622
if value.has_escaping_bound_vars() {
@@ -1624,7 +1625,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16241625
infcx
16251626
.can_eq(
16261627
ty::ParamEnv::empty(),
1627-
header.trait_ref.self_ty(),
1628+
trait_ref.self_ty(),
16281629
value,
16291630
) && header.polarity != ty::ImplPolarity::Negative
16301631
})
@@ -1677,9 +1678,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16771678
.filter(|header| {
16781679
// Consider only accessible traits
16791680
tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx)
1680-
&& header.skip_binder().polarity != ty::ImplPolarity::Negative
1681+
&& header.polarity != ty::ImplPolarity::Negative
16811682
})
1682-
.map(|header| header.instantiate_identity().trait_ref.self_ty())
1683+
.map(|header| header.trait_ref.instantiate_identity().self_ty())
16831684
// We don't care about blanket impls.
16841685
.filter(|self_ty| !self_ty.has_non_region_param())
16851686
.map(|self_ty| tcx.erase_regions(self_ty).to_string())

compiler/rustc_hir_analysis/src/check/check.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -540,11 +540,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
540540
}
541541
DefKind::Impl { of_trait } => {
542542
if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
543-
check_impl_items_against_trait(
544-
tcx,
545-
def_id,
546-
impl_trait_header.instantiate_identity(),
547-
);
543+
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
548544
check_on_unimplemented(tcx, def_id);
549545
}
550546
}
@@ -735,10 +731,11 @@ fn check_impl_items_against_trait<'tcx>(
735731
impl_id: LocalDefId,
736732
impl_trait_header: ty::ImplTraitHeader<'tcx>,
737733
) {
734+
let trait_ref = impl_trait_header.trait_ref.instantiate_identity();
738735
// If the trait reference itself is erroneous (so the compilation is going
739736
// to fail), skip checking the items here -- the `impl_item` table in `tcx`
740737
// isn't populated for such impls.
741-
if impl_trait_header.references_error() {
738+
if trait_ref.references_error() {
742739
return;
743740
}
744741

@@ -762,7 +759,7 @@ fn check_impl_items_against_trait<'tcx>(
762759
}
763760
}
764761

765-
let trait_def = tcx.trait_def(impl_trait_header.trait_ref.def_id);
762+
let trait_def = tcx.trait_def(trait_ref.def_id);
766763

767764
for &impl_item in impl_item_refs {
768765
let ty_impl_item = tcx.associated_item(impl_item);
@@ -781,10 +778,10 @@ fn check_impl_items_against_trait<'tcx>(
781778
));
782779
}
783780
ty::AssocKind::Fn => {
784-
compare_impl_method(tcx, ty_impl_item, ty_trait_item, impl_trait_header.trait_ref);
781+
compare_impl_method(tcx, ty_impl_item, ty_trait_item, trait_ref);
785782
}
786783
ty::AssocKind::Type => {
787-
compare_impl_ty(tcx, ty_impl_item, ty_trait_item, impl_trait_header.trait_ref);
784+
compare_impl_ty(tcx, ty_impl_item, ty_trait_item, trait_ref);
788785
}
789786
}
790787

@@ -804,7 +801,7 @@ fn check_impl_items_against_trait<'tcx>(
804801
let mut must_implement_one_of: Option<&[Ident]> =
805802
trait_def.must_implement_one_of.as_deref();
806803

807-
for &trait_item_id in tcx.associated_item_def_ids(impl_trait_header.trait_ref.def_id) {
804+
for &trait_item_id in tcx.associated_item_def_ids(trait_ref.def_id) {
808805
let leaf_def = ancestors.leaf_def(tcx, trait_item_id);
809806

810807
let is_implemented = leaf_def
@@ -882,7 +879,7 @@ fn check_impl_items_against_trait<'tcx>(
882879

883880
if let Some(missing_items) = must_implement_one_of {
884881
let attr_span = tcx
885-
.get_attr(impl_trait_header.trait_ref.def_id, sym::rustc_must_implement_one_of)
882+
.get_attr(trait_ref.def_id, sym::rustc_must_implement_one_of)
886883
.map(|attr| attr.span);
887884

888885
missing_items_must_implement_one_of_err(

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
247247
hir::ItemKind::Impl(impl_) => {
248248
let header = tcx.impl_trait_header(def_id);
249249
let is_auto = header
250-
.is_some_and(|header| tcx.trait_is_auto(header.skip_binder().trait_ref.def_id));
250+
.is_some_and(|header| tcx.trait_is_auto(header.trait_ref.skip_binder().def_id));
251251
let mut res = Ok(());
252252
if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) {
253253
let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span);
@@ -259,7 +259,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
259259
.emit());
260260
}
261261
// We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
262-
match header.map(|h| h.skip_binder().polarity) {
262+
match header.map(|h| h.polarity) {
263263
// `None` means this is an inherent impl
264264
Some(ty::ImplPolarity::Positive) | None => {
265265
res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait));

compiler/rustc_hir_analysis/src/coherence/builtin.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc_trait_selection::traits::ObligationCtxt;
2525
use rustc_trait_selection::traits::{self, ObligationCause};
2626
use std::collections::BTreeMap;
2727

28-
pub fn check_trait<'tcx>(
28+
pub(super) fn check_trait<'tcx>(
2929
tcx: TyCtxt<'tcx>,
3030
trait_def_id: DefId,
3131
impl_def_id: LocalDefId,
@@ -66,10 +66,9 @@ impl<'tcx> Checker<'tcx> {
6666

6767
fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
6868
let tcx = checker.tcx;
69-
let header = checker.impl_header;
7069
let impl_did = checker.impl_def_id;
7170
// Destructors only work on local ADT types.
72-
match header.trait_ref.self_ty().kind() {
71+
match checker.impl_header.trait_ref.instantiate_identity().self_ty().kind() {
7372
ty::Adt(def, _) if def.did().is_local() => return Ok(()),
7473
ty::Error(_) => return Ok(()),
7574
_ => {}
@@ -86,7 +85,7 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
8685
let impl_did = checker.impl_def_id;
8786
debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
8887

89-
let self_type = impl_header.trait_ref.self_ty();
88+
let self_type = impl_header.trait_ref.instantiate_identity().self_ty();
9089
debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type);
9190

9291
let param_env = tcx.param_env(impl_did);
@@ -120,7 +119,7 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E
120119
let tcx = checker.tcx;
121120
let header = checker.impl_header;
122121
let impl_did = checker.impl_def_id;
123-
let self_type = header.trait_ref.self_ty();
122+
let self_type = header.trait_ref.instantiate_identity().self_ty();
124123
assert!(!self_type.has_escaping_bound_vars());
125124

126125
let param_env = tcx.param_env(impl_did);
@@ -157,9 +156,8 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E
157156

158157
fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
159158
let tcx = checker.tcx;
160-
let header = checker.impl_header;
161159
let impl_did = checker.impl_def_id;
162-
let trait_ref = header.trait_ref;
160+
let trait_ref = checker.impl_header.trait_ref.instantiate_identity();
163161
debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did);
164162

165163
let span = tcx.def_span(impl_did);

compiler/rustc_hir_analysis/src/coherence/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,12 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
134134
let mut res = tcx.ensure().specialization_graph_of(def_id);
135135

136136
for &impl_def_id in impls {
137-
let trait_header = tcx.impl_trait_header(impl_def_id).unwrap().instantiate_identity();
138-
let trait_def = tcx.trait_def(trait_header.trait_ref.def_id);
137+
let trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
138+
let trait_ref = trait_header.trait_ref.instantiate_identity();
139+
let trait_def = tcx.trait_def(trait_ref.def_id);
139140

140-
res = res.and(check_impl(tcx, impl_def_id, trait_header.trait_ref, trait_def));
141-
res = res.and(check_object_overlap(tcx, impl_def_id, trait_header.trait_ref));
141+
res = res.and(check_impl(tcx, impl_def_id, trait_ref, trait_def));
142+
res = res.and(check_object_overlap(tcx, impl_def_id, trait_ref));
142143

143144
res = res.and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def));
144145
res = res.and(tcx.ensure().orphan_check_impl(impl_def_id));

compiler/rustc_hir_analysis/src/coherence/unsafety.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ pub(super) fn check_item(
1313
trait_header: ImplTraitHeader<'_>,
1414
trait_def: &TraitDef,
1515
) -> Result<(), ErrorGuaranteed> {
16-
let trait_ref = trait_header.trait_ref;
1716
let unsafe_attr =
1817
tcx.generics_of(def_id).params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
18+
let trait_ref = trait_header.trait_ref.instantiate_identity();
19+
1920
match (trait_def.unsafety, unsafe_attr, trait_header.unsafety, trait_header.polarity) {
2021
(Unsafety::Normal, None, Unsafety::Unsafe, Positive | Reservation) => {
2122
let span = tcx.def_span(def_id);

compiler/rustc_hir_analysis/src/collect.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -1514,10 +1514,7 @@ fn suggest_impl_trait<'tcx>(
15141514
None
15151515
}
15161516

1517-
fn impl_trait_header(
1518-
tcx: TyCtxt<'_>,
1519-
def_id: LocalDefId,
1520-
) -> Option<ty::EarlyBinder<ty::ImplTraitHeader<'_>>> {
1517+
fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTraitHeader<'_>> {
15211518
let icx = ItemCtxt::new(tcx, def_id);
15221519
let item = tcx.hir().expect_item(def_id);
15231520
let impl_ = item.expect_impl();
@@ -1553,11 +1550,11 @@ fn impl_trait_header(
15531550
} else {
15541551
icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty)
15551552
};
1556-
ty::EarlyBinder::bind(ty::ImplTraitHeader {
1557-
trait_ref,
1553+
ty::ImplTraitHeader {
1554+
trait_ref: ty::EarlyBinder::bind(trait_ref),
15581555
unsafety: impl_.unsafety,
15591556
polarity: polarity_of_impl(tcx, def_id, impl_, item.span)
1560-
})
1557+
}
15611558
})
15621559
}
15631560

compiler/rustc_hir_typeck/src/method/suggest.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -3368,11 +3368,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
33683368
"inherent impls can't be candidates, only trait impls can be",
33693369
)
33703370
})
3371-
.filter(|header| {
3372-
header.skip_binder().polarity == ty::ImplPolarity::Negative
3373-
})
3371+
.filter(|header| header.polarity == ty::ImplPolarity::Negative)
33743372
.any(|header| {
3375-
let imp = header.instantiate_identity().trait_ref;
3373+
let imp = header.trait_ref.instantiate_identity();
33763374
let imp_simp =
33773375
simplify_type(self.tcx, imp.self_ty(), TreatParams::ForLookup);
33783376
imp_simp.is_some_and(|s| s == simp_rcvr_ty)

compiler/rustc_metadata/src/rmeta/encoder.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1981,9 +1981,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
19811981

19821982
if of_trait && let Some(header) = tcx.impl_trait_header(def_id) {
19831983
record!(self.tables.impl_trait_header[def_id] <- header);
1984-
let trait_ref = header.map_bound(|h| h.trait_ref);
19851984

1986-
let trait_ref = trait_ref.instantiate_identity();
1985+
let trait_ref = header.trait_ref.instantiate_identity();
19871986
let simplified_self_ty = fast_reject::simplify_type(
19881987
self.tcx,
19891988
trait_ref.self_ty(),

compiler/rustc_metadata/src/rmeta/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ define_tables! {
423423
variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
424424
fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::PolyFnSig<'static>>>>,
425425
codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
426-
impl_trait_header: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::ImplTraitHeader<'static>>>>,
426+
impl_trait_header: Table<DefIndex, LazyValue<ty::ImplTraitHeader<'static>>>,
427427
const_param_default: Table<DefIndex, LazyValue<ty::EarlyBinder<rustc_middle::ty::Const<'static>>>>,
428428
object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
429429
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,

compiler/rustc_middle/src/query/erase.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ impl EraseType for Option<mir::DestructuredConstant<'_>> {
177177
type Result = [u8; size_of::<Option<mir::DestructuredConstant<'static>>>()];
178178
}
179179

180-
impl EraseType for Option<ty::EarlyBinder<ty::ImplTraitHeader<'_>>> {
181-
type Result = [u8; size_of::<Option<ty::EarlyBinder<ty::ImplTraitHeader<'static>>>>()];
180+
impl EraseType for Option<ty::ImplTraitHeader<'_>> {
181+
type Result = [u8; size_of::<Option<ty::ImplTraitHeader<'static>>>()];
182182
}
183183

184184
impl EraseType for Option<ty::EarlyBinder<Ty<'_>>> {

compiler/rustc_middle/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ rustc_queries! {
849849

850850
/// Given an `impl_id`, return the trait it implements along with some header information.
851851
/// Return `None` if this is an inherent impl.
852-
query impl_trait_header(impl_id: DefId) -> Option<ty::EarlyBinder<ty::ImplTraitHeader<'tcx>>> {
852+
query impl_trait_header(impl_id: DefId) -> Option<ty::ImplTraitHeader<'tcx>> {
853853
desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) }
854854
cache_on_disk_if { impl_id.is_local() }
855855
separate_provide_extern

compiler/rustc_middle/src/ty/context.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2310,12 +2310,11 @@ impl<'tcx> TyCtxt<'tcx> {
23102310
self,
23112311
def_id: impl IntoQueryParam<DefId>,
23122312
) -> Option<ty::EarlyBinder<ty::TraitRef<'tcx>>> {
2313-
Some(self.impl_trait_header(def_id)?.map_bound(|h| h.trait_ref))
2313+
Some(self.impl_trait_header(def_id)?.trait_ref)
23142314
}
23152315

23162316
pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
2317-
self.impl_trait_header(def_id)
2318-
.map_or(ty::ImplPolarity::Positive, |h| h.skip_binder().polarity)
2317+
self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
23192318
}
23202319
}
23212320

compiler/rustc_middle/src/ty/mod.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,9 @@ pub struct ImplHeader<'tcx> {
251251
pub predicates: Vec<Predicate<'tcx>>,
252252
}
253253

254-
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, TyEncodable, TyDecodable, HashStable)]
254+
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
255255
pub struct ImplTraitHeader<'tcx> {
256-
pub trait_ref: ty::TraitRef<'tcx>,
256+
pub trait_ref: ty::EarlyBinder<ty::TraitRef<'tcx>>,
257257
pub polarity: ImplPolarity,
258258
pub unsafety: hir::Unsafety,
259259
}
@@ -1625,12 +1625,15 @@ impl<'tcx> TyCtxt<'tcx> {
16251625
def_id1: DefId,
16261626
def_id2: DefId,
16271627
) -> Option<ImplOverlapKind> {
1628-
let impl1 = self.impl_trait_header(def_id1).unwrap().instantiate_identity();
1629-
let impl2 = self.impl_trait_header(def_id2).unwrap().instantiate_identity();
1628+
let impl1 = self.impl_trait_header(def_id1).unwrap();
1629+
let impl2 = self.impl_trait_header(def_id2).unwrap();
1630+
1631+
let trait_ref1 = impl1.trait_ref.skip_binder();
1632+
let trait_ref2 = impl2.trait_ref.skip_binder();
16301633

16311634
// If either trait impl references an error, they're allowed to overlap,
16321635
// as one of them essentially doesn't exist.
1633-
if impl1.references_error() || impl2.references_error() {
1636+
if trait_ref1.references_error() || trait_ref2.references_error() {
16341637
return Some(ImplOverlapKind::Permitted { marker: false });
16351638
}
16361639

@@ -1651,7 +1654,7 @@ impl<'tcx> TyCtxt<'tcx> {
16511654
let is_marker_overlap = {
16521655
let is_marker_impl =
16531656
|trait_ref: TraitRef<'_>| -> bool { self.trait_def(trait_ref.def_id).is_marker };
1654-
is_marker_impl(impl1.trait_ref) && is_marker_impl(impl2.trait_ref)
1657+
is_marker_impl(trait_ref1) && is_marker_impl(trait_ref2)
16551658
};
16561659

16571660
if is_marker_overlap {

compiler/rustc_monomorphize/src/collector.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1361,7 +1361,7 @@ fn create_mono_items_for_default_impls<'tcx>(
13611361
return;
13621362
};
13631363

1364-
if matches!(impl_.skip_binder().polarity, ty::ImplPolarity::Negative) {
1364+
if matches!(impl_.polarity, ty::ImplPolarity::Negative) {
13651365
return;
13661366
}
13671367

@@ -1385,7 +1385,7 @@ fn create_mono_items_for_default_impls<'tcx>(
13851385
}
13861386
};
13871387
let impl_args = GenericArgs::for_item(tcx, item.owner_id.to_def_id(), only_region_params);
1388-
let trait_ref = impl_.instantiate(tcx, impl_args).trait_ref;
1388+
let trait_ref = impl_.trait_ref.instantiate(tcx, impl_args);
13891389

13901390
// Unlike 'lazy' monomorphization that begins by collecting items transitively
13911391
// called by `main` or other global items, when eagerly monomorphizing impl

compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
166166
let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup };
167167
if !drcx.args_may_unify(
168168
goal.predicate.trait_ref(tcx).args,
169-
impl_trait_header.skip_binder().trait_ref.args,
169+
impl_trait_header.trait_ref.skip_binder().args,
170170
) {
171171
return Err(NoSolution);
172172
}
173173

174174
// We have to ignore negative impls when projecting.
175-
let impl_polarity = impl_trait_header.skip_binder().polarity;
175+
let impl_polarity = impl_trait_header.polarity;
176176
match impl_polarity {
177177
ty::ImplPolarity::Negative => return Err(NoSolution),
178178
ty::ImplPolarity::Reservation => {
@@ -183,7 +183,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
183183

184184
ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
185185
let impl_args = ecx.fresh_args_for_item(impl_def_id);
186-
let impl_trait_ref = impl_trait_header.instantiate(tcx, impl_args).trait_ref;
186+
let impl_trait_ref = impl_trait_header.trait_ref.instantiate(tcx, impl_args);
187187

188188
ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
189189

0 commit comments

Comments
 (0)