Skip to content

Commit d26b417

Browse files
committed
Auto merge of rust-lang#120919 - oli-obk:impl_polarity, r=compiler-errors
Merge `impl_polarity` and `impl_trait_ref` queries Hopefully this is perf neutral. I want to finish rust-lang#120835 and stop using the HIR in `coherent_trait`, which should then give us a perf improvement.
2 parents 0a5b998 + 74c9dff commit d26b417

File tree

22 files changed

+156
-131
lines changed

22 files changed

+156
-131
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -1673,9 +1673,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16731673
.is_accessible_from(self.item_def_id(), tcx)
16741674
&& tcx.all_impls(*trait_def_id)
16751675
.any(|impl_def_id| {
1676-
let trait_ref = tcx.impl_trait_ref(impl_def_id);
1677-
trait_ref.is_some_and(|trait_ref| {
1678-
let impl_ = trait_ref.instantiate(
1676+
let impl_header = tcx.impl_trait_header(impl_def_id);
1677+
impl_header.is_some_and(|header| {
1678+
let header = header.instantiate(
16791679
tcx,
16801680
infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
16811681
);
@@ -1687,11 +1687,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16871687
infcx
16881688
.can_eq(
16891689
ty::ParamEnv::empty(),
1690-
impl_.self_ty(),
1690+
header.trait_ref.self_ty(),
16911691
value,
1692-
)
1692+
) && header.polarity != ty::ImplPolarity::Negative
16931693
})
1694-
&& tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
16951694
})
16961695
})
16971696
.map(|trait_def_id| tcx.def_path_str(trait_def_id))
@@ -1737,13 +1736,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
17371736
} else {
17381737
// Find all the types that have an `impl` for the trait.
17391738
tcx.all_impls(trait_def_id)
1740-
.filter(|impl_def_id| {
1739+
.filter_map(|impl_def_id| tcx.impl_trait_header(impl_def_id))
1740+
.filter(|header| {
17411741
// Consider only accessible traits
17421742
tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx)
1743-
&& tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
1743+
&& header.skip_binder().polarity != ty::ImplPolarity::Negative
17441744
})
1745-
.filter_map(|impl_def_id| tcx.impl_trait_ref(impl_def_id))
1746-
.map(|impl_| impl_.instantiate_identity().self_ty())
1745+
.map(|header| header.instantiate_identity().trait_ref.self_ty())
17471746
// We don't care about blanket impls.
17481747
.filter(|self_ty| !self_ty.has_non_region_param())
17491748
.map(|self_ty| tcx.erase_regions(self_ty).to_string())

compiler/rustc_hir_analysis/src/check/check.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -527,8 +527,12 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
527527
}
528528
DefKind::Fn => {} // entirely within check_item_body
529529
DefKind::Impl { of_trait } => {
530-
if of_trait && let Some(impl_trait_ref) = tcx.impl_trait_ref(def_id) {
531-
check_impl_items_against_trait(tcx, def_id, impl_trait_ref.instantiate_identity());
530+
if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
531+
check_impl_items_against_trait(
532+
tcx,
533+
def_id,
534+
impl_trait_header.instantiate_identity(),
535+
);
532536
check_on_unimplemented(tcx, def_id);
533537
}
534538
}
@@ -719,19 +723,19 @@ pub(super) fn check_specialization_validity<'tcx>(
719723
fn check_impl_items_against_trait<'tcx>(
720724
tcx: TyCtxt<'tcx>,
721725
impl_id: LocalDefId,
722-
impl_trait_ref: ty::TraitRef<'tcx>,
726+
impl_trait_header: ty::ImplTraitHeader<'tcx>,
723727
) {
724728
// If the trait reference itself is erroneous (so the compilation is going
725729
// to fail), skip checking the items here -- the `impl_item` table in `tcx`
726730
// isn't populated for such impls.
727-
if impl_trait_ref.references_error() {
731+
if impl_trait_header.references_error() {
728732
return;
729733
}
730734

731735
let impl_item_refs = tcx.associated_item_def_ids(impl_id);
732736

733737
// Negative impls are not expected to have any items
734-
match tcx.impl_polarity(impl_id) {
738+
match impl_trait_header.polarity {
735739
ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
736740
ty::ImplPolarity::Negative => {
737741
if let [first_item_ref, ..] = impl_item_refs {
@@ -748,7 +752,7 @@ fn check_impl_items_against_trait<'tcx>(
748752
}
749753
}
750754

751-
let trait_def = tcx.trait_def(impl_trait_ref.def_id);
755+
let trait_def = tcx.trait_def(impl_trait_header.trait_ref.def_id);
752756

753757
for &impl_item in impl_item_refs {
754758
let ty_impl_item = tcx.associated_item(impl_item);
@@ -767,10 +771,10 @@ fn check_impl_items_against_trait<'tcx>(
767771
));
768772
}
769773
ty::AssocKind::Fn => {
770-
compare_impl_method(tcx, ty_impl_item, ty_trait_item, impl_trait_ref);
774+
compare_impl_method(tcx, ty_impl_item, ty_trait_item, impl_trait_header.trait_ref);
771775
}
772776
ty::AssocKind::Type => {
773-
compare_impl_ty(tcx, ty_impl_item, ty_trait_item, impl_trait_ref);
777+
compare_impl_ty(tcx, ty_impl_item, ty_trait_item, impl_trait_header.trait_ref);
774778
}
775779
}
776780

@@ -790,7 +794,7 @@ fn check_impl_items_against_trait<'tcx>(
790794
let mut must_implement_one_of: Option<&[Ident]> =
791795
trait_def.must_implement_one_of.as_deref();
792796

793-
for &trait_item_id in tcx.associated_item_def_ids(impl_trait_ref.def_id) {
797+
for &trait_item_id in tcx.associated_item_def_ids(impl_trait_header.trait_ref.def_id) {
794798
let leaf_def = ancestors.leaf_def(tcx, trait_item_id);
795799

796800
let is_implemented = leaf_def
@@ -868,7 +872,7 @@ fn check_impl_items_against_trait<'tcx>(
868872

869873
if let Some(missing_items) = must_implement_one_of {
870874
let attr_span = tcx
871-
.get_attr(impl_trait_ref.def_id, sym::rustc_must_implement_one_of)
875+
.get_attr(impl_trait_header.trait_ref.def_id, sym::rustc_must_implement_one_of)
872876
.map(|attr| attr.span);
873877

874878
missing_items_must_implement_one_of_err(

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,9 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
245245
// won't be allowed unless there's an *explicit* implementation of `Send`
246246
// for `T`
247247
hir::ItemKind::Impl(impl_) => {
248-
let is_auto = tcx
249-
.impl_trait_ref(def_id)
250-
.is_some_and(|trait_ref| tcx.trait_is_auto(trait_ref.skip_binder().def_id));
248+
let header = tcx.impl_trait_header(def_id);
249+
let is_auto = header
250+
.is_some_and(|header| tcx.trait_is_auto(header.skip_binder().trait_ref.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,11 +259,12 @@ 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 tcx.impl_polarity(def_id) {
263-
ty::ImplPolarity::Positive => {
262+
match header.map(|h| h.skip_binder().polarity) {
263+
// `None` means this is an inherent impl
264+
Some(ty::ImplPolarity::Positive) | None => {
264265
res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait));
265266
}
266-
ty::ImplPolarity::Negative => {
267+
Some(ty::ImplPolarity::Negative) => {
267268
let ast::ImplPolarity::Negative(span) = impl_.polarity else {
268269
bug!("impl_polarity query disagrees with impl's polarity in AST");
269270
};
@@ -280,7 +281,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
280281
.emit());
281282
}
282283
}
283-
ty::ImplPolarity::Reservation => {
284+
Some(ty::ImplPolarity::Reservation) => {
284285
// FIXME: what amount of WF checking do we need for reservation impls?
285286
}
286287
}

compiler/rustc_hir_analysis/src/collect.rs

+23-29
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ pub fn provide(providers: &mut Providers) {
7979
trait_def,
8080
adt_def,
8181
fn_sig,
82-
impl_trait_ref,
83-
impl_polarity,
82+
impl_trait_header,
8483
coroutine_kind,
8584
coroutine_for_closure,
8685
collect_mod_item_types,
@@ -600,7 +599,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
600599
hir::ItemKind::Impl { .. } => {
601600
tcx.ensure().generics_of(def_id);
602601
tcx.ensure().type_of(def_id);
603-
tcx.ensure().impl_trait_ref(def_id);
602+
tcx.ensure().impl_trait_header(def_id);
604603
tcx.ensure().predicates_of(def_id);
605604
}
606605
hir::ItemKind::Trait(..) => {
@@ -1499,19 +1498,20 @@ fn suggest_impl_trait<'tcx>(
14991498
None
15001499
}
15011500

1502-
fn impl_trait_ref(
1501+
fn impl_trait_header(
15031502
tcx: TyCtxt<'_>,
15041503
def_id: LocalDefId,
1505-
) -> Option<ty::EarlyBinder<ty::TraitRef<'_>>> {
1504+
) -> Option<ty::EarlyBinder<ty::ImplTraitHeader<'_>>> {
15061505
let icx = ItemCtxt::new(tcx, def_id);
1507-
let impl_ = tcx.hir().expect_item(def_id).expect_impl();
1506+
let item = tcx.hir().expect_item(def_id);
1507+
let impl_ = item.expect_impl();
15081508
impl_
15091509
.of_trait
15101510
.as_ref()
15111511
.map(|ast_trait_ref| {
15121512
let selfty = tcx.type_of(def_id).instantiate_identity();
15131513

1514-
if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
1514+
let trait_ref = if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
15151515
tcx,
15161516
tcx.is_const_trait_impl_raw(def_id.to_def_id()),
15171517
ast_trait_ref,
@@ -1536,9 +1536,12 @@ fn impl_trait_ref(
15361536
icx.astconv().instantiate_mono_trait_ref(trait_ref, selfty)
15371537
} else {
15381538
icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty)
1539-
}
1539+
};
1540+
ty::EarlyBinder::bind(ty::ImplTraitHeader {
1541+
trait_ref,
1542+
polarity: polarity_of_impl(tcx, def_id, impl_, item.span)
1543+
})
15401544
})
1541-
.map(ty::EarlyBinder::bind)
15421545
}
15431546

15441547
fn check_impl_constness(
@@ -1566,43 +1569,34 @@ fn check_impl_constness(
15661569
}))
15671570
}
15681571

1569-
fn impl_polarity(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplPolarity {
1572+
fn polarity_of_impl(
1573+
tcx: TyCtxt<'_>,
1574+
def_id: LocalDefId,
1575+
impl_: &hir::Impl<'_>,
1576+
span: Span,
1577+
) -> ty::ImplPolarity {
15701578
let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
1571-
let item = tcx.hir().expect_item(def_id);
1572-
match &item.kind {
1573-
hir::ItemKind::Impl(hir::Impl {
1574-
polarity: hir::ImplPolarity::Negative(span),
1575-
of_trait,
1576-
..
1577-
}) => {
1579+
match &impl_ {
1580+
hir::Impl { polarity: hir::ImplPolarity::Negative(span), of_trait, .. } => {
15781581
if is_rustc_reservation {
15791582
let span = span.to(of_trait.as_ref().map_or(*span, |t| t.path.span));
15801583
tcx.dcx().span_err(span, "reservation impls can't be negative");
15811584
}
15821585
ty::ImplPolarity::Negative
15831586
}
1584-
hir::ItemKind::Impl(hir::Impl {
1585-
polarity: hir::ImplPolarity::Positive,
1586-
of_trait: None,
1587-
..
1588-
}) => {
1587+
hir::Impl { polarity: hir::ImplPolarity::Positive, of_trait: None, .. } => {
15891588
if is_rustc_reservation {
1590-
tcx.dcx().span_err(item.span, "reservation impls can't be inherent");
1589+
tcx.dcx().span_err(span, "reservation impls can't be inherent");
15911590
}
15921591
ty::ImplPolarity::Positive
15931592
}
1594-
hir::ItemKind::Impl(hir::Impl {
1595-
polarity: hir::ImplPolarity::Positive,
1596-
of_trait: Some(_),
1597-
..
1598-
}) => {
1593+
hir::Impl { polarity: hir::ImplPolarity::Positive, of_trait: Some(_), .. } => {
15991594
if is_rustc_reservation {
16001595
ty::ImplPolarity::Reservation
16011596
} else {
16021597
ty::ImplPolarity::Positive
16031598
}
16041599
}
1605-
item => bug!("impl_polarity: {:?} not an impl", item),
16061600
}
16071601
}
16081602

compiler/rustc_hir_typeck/src/method/suggest.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -3134,12 +3134,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
31343134
if self
31353135
.tcx
31363136
.all_impls(candidate.def_id)
3137-
.filter(|imp_did| {
3138-
self.tcx.impl_polarity(*imp_did) == ty::ImplPolarity::Negative
3137+
.map(|imp_did| {
3138+
self.tcx.impl_trait_header(imp_did).expect(
3139+
"inherent impls can't be candidates, only trait impls can be",
3140+
)
3141+
})
3142+
.filter(|header| {
3143+
header.skip_binder().polarity == ty::ImplPolarity::Negative
31393144
})
3140-
.any(|imp_did| {
3141-
let imp =
3142-
self.tcx.impl_trait_ref(imp_did).unwrap().instantiate_identity();
3145+
.any(|header| {
3146+
let imp = header.instantiate_identity().trait_ref;
31433147
let imp_simp =
31443148
simplify_type(self.tcx, imp.self_ty(), TreatParams::ForLookup);
31453149
imp_simp.is_some_and(|s| s == simp_rcvr_ty)

compiler/rustc_incremental/src/persist/dirty_clean.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const BASE_HIR: &[&str] = &[
6363

6464
/// `impl` implementation of struct/trait
6565
const BASE_IMPL: &[&str] =
66-
&[label_strs::associated_item_def_ids, label_strs::generics_of, label_strs::impl_trait_ref];
66+
&[label_strs::associated_item_def_ids, label_strs::generics_of, label_strs::impl_trait_header];
6767

6868
/// DepNodes for mir_built/Optimized, which is relevant in "executable"
6969
/// code, i.e., functions+methods

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ provide! { tcx, def_id, other, cdata,
215215
variances_of => { table }
216216
fn_sig => { table }
217217
codegen_fn_attrs => { table }
218-
impl_trait_ref => { table }
218+
impl_trait_header => { table }
219219
const_param_default => { table }
220220
object_lifetime_default => { table }
221221
thir_abstract_const => { table }
@@ -234,7 +234,6 @@ provide! { tcx, def_id, other, cdata,
234234
unused_generic_params => { cdata.root.tables.unused_generic_params.get(cdata, def_id.index) }
235235
def_kind => { cdata.def_kind(def_id.index) }
236236
impl_parent => { table }
237-
impl_polarity => { table_direct }
238237
defaultness => { table_direct }
239238
constness => { table_direct }
240239
coerce_unsized_info => {

compiler/rustc_metadata/src/rmeta/encoder.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1969,10 +1969,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
19691969
let def_id = id.owner_id.to_def_id();
19701970

19711971
self.tables.defaultness.set_some(def_id.index, tcx.defaultness(def_id));
1972-
self.tables.impl_polarity.set_some(def_id.index, tcx.impl_polarity(def_id));
19731972

1974-
if of_trait && let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
1975-
record!(self.tables.impl_trait_ref[def_id] <- trait_ref);
1973+
if of_trait && let Some(header) = tcx.impl_trait_header(def_id) {
1974+
record!(self.tables.impl_trait_header[def_id] <- header);
1975+
let trait_ref = header.map_bound(|h| h.trait_ref);
19761976

19771977
let trait_ref = trait_ref.instantiate_identity();
19781978
let simplified_self_ty = fast_reject::simplify_type(

compiler/rustc_metadata/src/rmeta/mod.rs

+1-2
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_ref: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::TraitRef<'static>>>>,
426+
impl_trait_header: Table<DefIndex, LazyValue<ty::EarlyBinder<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>>>,
@@ -433,7 +433,6 @@ define_tables! {
433433
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
434434
thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::Const<'static>>>>,
435435
impl_parent: Table<DefIndex, RawDefId>,
436-
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
437436
constness: Table<DefIndex, hir::Constness>,
438437
defaultness: Table<DefIndex, hir::Defaultness>,
439438
// FIXME(eddyb) perhaps compute this on the fly if cheap enough?

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

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

compiler/rustc_middle/src/query/mod.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -846,17 +846,13 @@ rustc_queries! {
846846
cache_on_disk_if { true }
847847
}
848848

849-
/// Given an `impl_id`, return the trait it implements.
849+
/// Given an `impl_id`, return the trait it implements along with some header information.
850850
/// Return `None` if this is an inherent impl.
851-
query impl_trait_ref(impl_id: DefId) -> Option<ty::EarlyBinder<ty::TraitRef<'tcx>>> {
851+
query impl_trait_header(impl_id: DefId) -> Option<ty::EarlyBinder<ty::ImplTraitHeader<'tcx>>> {
852852
desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) }
853853
cache_on_disk_if { impl_id.is_local() }
854854
separate_provide_extern
855855
}
856-
query impl_polarity(impl_id: DefId) -> ty::ImplPolarity {
857-
desc { |tcx| "computing implementation polarity of `{}`", tcx.def_path_str(impl_id) }
858-
separate_provide_extern
859-
}
860856

861857
query issue33140_self_ty(key: DefId) -> Option<ty::EarlyBinder<ty::Ty<'tcx>>> {
862858
desc { |tcx| "computing Self type wrt issue #33140 `{}`", tcx.def_path_str(key) }

0 commit comments

Comments
 (0)