Skip to content

Commit a711662

Browse files
committed
Auto merge of rust-lang#120919 - oli-obk:impl_polarity, r=<try>
Merge `impl_polarity` and `impl_trait_ref` queries Hopefully this is perf neutral. I wan to finish rust-lang#120835 and stop using the HIR in `coherent_trait`, which should then give us a perf improvement.
2 parents 9aa232e + 1ce3522 commit a711662

File tree

22 files changed

+151
-131
lines changed

22 files changed

+151
-131
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -1671,9 +1671,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16711671
.is_accessible_from(self.item_def_id(), tcx)
16721672
&& tcx.all_impls(*trait_def_id)
16731673
.any(|impl_def_id| {
1674-
let trait_ref = tcx.impl_trait_ref(impl_def_id);
1675-
trait_ref.is_some_and(|trait_ref| {
1676-
let impl_ = trait_ref.instantiate(
1674+
let impl_header = tcx.impl_trait_header(impl_def_id);
1675+
impl_header.is_some_and(|header| {
1676+
let header = header.instantiate(
16771677
tcx,
16781678
infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
16791679
);
@@ -1685,11 +1685,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16851685
infcx
16861686
.can_eq(
16871687
ty::ParamEnv::empty(),
1688-
impl_.self_ty(),
1688+
header.trait_ref.self_ty(),
16891689
value,
1690-
)
1690+
) && header.polarity != ty::ImplPolarity::Negative
16911691
})
1692-
&& tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
16931692
})
16941693
})
16951694
.map(|trait_def_id| tcx.def_path_str(trait_def_id))
@@ -1735,13 +1734,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
17351734
} else {
17361735
// Find all the types that have an `impl` for the trait.
17371736
tcx.all_impls(trait_def_id)
1738-
.filter(|impl_def_id| {
1737+
.filter_map(|impl_def_id| tcx.impl_trait_header(impl_def_id))
1738+
.filter(|header| {
17391739
// Consider only accessible traits
17401740
tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx)
1741-
&& tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
1741+
&& header.skip_binder().polarity != ty::ImplPolarity::Negative
17421742
})
1743-
.filter_map(|impl_def_id| tcx.impl_trait_ref(impl_def_id))
1744-
.map(|impl_| impl_.instantiate_identity().self_ty())
1743+
.map(|header| header.instantiate_identity().trait_ref.self_ty())
17451744
// We don't care about blanket impls.
17461745
.filter(|self_ty| !self_ty.has_non_region_param())
17471746
.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
@@ -474,8 +474,12 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
474474
}
475475
DefKind::Fn => {} // entirely within check_item_body
476476
DefKind::Impl { of_trait } => {
477-
if of_trait && let Some(impl_trait_ref) = tcx.impl_trait_ref(def_id) {
478-
check_impl_items_against_trait(tcx, def_id, impl_trait_ref.instantiate_identity());
477+
if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
478+
check_impl_items_against_trait(
479+
tcx,
480+
def_id,
481+
impl_trait_header.instantiate_identity(),
482+
);
479483
check_on_unimplemented(tcx, def_id);
480484
}
481485
}
@@ -666,19 +670,19 @@ pub(super) fn check_specialization_validity<'tcx>(
666670
fn check_impl_items_against_trait<'tcx>(
667671
tcx: TyCtxt<'tcx>,
668672
impl_id: LocalDefId,
669-
impl_trait_ref: ty::TraitRef<'tcx>,
673+
impl_trait_header: ty::ImplTraitHeader<'tcx>,
670674
) {
671675
// If the trait reference itself is erroneous (so the compilation is going
672676
// to fail), skip checking the items here -- the `impl_item` table in `tcx`
673677
// isn't populated for such impls.
674-
if impl_trait_ref.references_error() {
678+
if impl_trait_header.references_error() {
675679
return;
676680
}
677681

678682
let impl_item_refs = tcx.associated_item_def_ids(impl_id);
679683

680684
// Negative impls are not expected to have any items
681-
match tcx.impl_polarity(impl_id) {
685+
match impl_trait_header.polarity {
682686
ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
683687
ty::ImplPolarity::Negative => {
684688
if let [first_item_ref, ..] = impl_item_refs {
@@ -695,7 +699,7 @@ fn check_impl_items_against_trait<'tcx>(
695699
}
696700
}
697701

698-
let trait_def = tcx.trait_def(impl_trait_ref.def_id);
702+
let trait_def = tcx.trait_def(impl_trait_header.trait_ref.def_id);
699703

700704
for &impl_item in impl_item_refs {
701705
let ty_impl_item = tcx.associated_item(impl_item);
@@ -714,10 +718,10 @@ fn check_impl_items_against_trait<'tcx>(
714718
));
715719
}
716720
ty::AssocKind::Fn => {
717-
compare_impl_method(tcx, ty_impl_item, ty_trait_item, impl_trait_ref);
721+
compare_impl_method(tcx, ty_impl_item, ty_trait_item, impl_trait_header.trait_ref);
718722
}
719723
ty::AssocKind::Type => {
720-
compare_impl_ty(tcx, ty_impl_item, ty_trait_item, impl_trait_ref);
724+
compare_impl_ty(tcx, ty_impl_item, ty_trait_item, impl_trait_header.trait_ref);
721725
}
722726
}
723727

@@ -737,7 +741,7 @@ fn check_impl_items_against_trait<'tcx>(
737741
let mut must_implement_one_of: Option<&[Ident]> =
738742
trait_def.must_implement_one_of.as_deref();
739743

740-
for &trait_item_id in tcx.associated_item_def_ids(impl_trait_ref.def_id) {
744+
for &trait_item_id in tcx.associated_item_def_ids(impl_trait_header.trait_ref.def_id) {
741745
let leaf_def = ancestors.leaf_def(tcx, trait_item_id);
742746

743747
let is_implemented = leaf_def
@@ -815,7 +819,7 @@ fn check_impl_items_against_trait<'tcx>(
815819

816820
if let Some(missing_items) = must_implement_one_of {
817821
let attr_span = tcx
818-
.get_attr(impl_trait_ref.def_id, sym::rustc_must_implement_one_of)
822+
.get_attr(impl_trait_header.trait_ref.def_id, sym::rustc_must_implement_one_of)
819823
.map(|attr| attr.span);
820824

821825
missing_items_must_implement_one_of_err(

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+7-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,11 @@ 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+
Some(ty::ImplPolarity::Positive) | None => {
264264
res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait));
265265
}
266-
ty::ImplPolarity::Negative => {
266+
Some(ty::ImplPolarity::Negative) => {
267267
let ast::ImplPolarity::Negative(span) = impl_.polarity else {
268268
bug!("impl_polarity query disagrees with impl's polarity in AST");
269269
};
@@ -280,7 +280,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
280280
.emit());
281281
}
282282
}
283-
ty::ImplPolarity::Reservation => {
283+
Some(ty::ImplPolarity::Reservation) => {
284284
// FIXME: what amount of WF checking do we need for reservation impls?
285285
}
286286
}

compiler/rustc_hir_analysis/src/collect.rs

+23-29
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ pub fn provide(providers: &mut Providers) {
7878
trait_def,
7979
adt_def,
8080
fn_sig,
81-
impl_trait_ref,
82-
impl_polarity,
81+
impl_trait_header,
8382
coroutine_kind,
8483
coroutine_for_closure,
8584
collect_mod_item_types,
@@ -601,7 +600,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
601600
hir::ItemKind::Impl { .. } => {
602601
tcx.ensure().generics_of(def_id);
603602
tcx.ensure().type_of(def_id);
604-
tcx.ensure().impl_trait_ref(def_id);
603+
tcx.ensure().impl_trait_header(def_id);
605604
tcx.ensure().predicates_of(def_id);
606605
}
607606
hir::ItemKind::Trait(..) => {
@@ -1326,19 +1325,20 @@ fn suggest_impl_trait<'tcx>(
13261325
None
13271326
}
13281327

1329-
fn impl_trait_ref(
1328+
fn impl_trait_header(
13301329
tcx: TyCtxt<'_>,
13311330
def_id: LocalDefId,
1332-
) -> Option<ty::EarlyBinder<ty::TraitRef<'_>>> {
1331+
) -> Option<ty::EarlyBinder<ty::ImplTraitHeader<'_>>> {
13331332
let icx = ItemCtxt::new(tcx, def_id);
1334-
let impl_ = tcx.hir().expect_item(def_id).expect_impl();
1333+
let item = tcx.hir().expect_item(def_id);
1334+
let impl_ = item.expect_impl();
13351335
impl_
13361336
.of_trait
13371337
.as_ref()
13381338
.map(|ast_trait_ref| {
13391339
let selfty = tcx.type_of(def_id).instantiate_identity();
13401340

1341-
if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
1341+
let trait_ref = if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
13421342
tcx,
13431343
tcx.is_const_trait_impl_raw(def_id.to_def_id()),
13441344
ast_trait_ref,
@@ -1363,9 +1363,12 @@ fn impl_trait_ref(
13631363
icx.astconv().instantiate_mono_trait_ref(trait_ref, selfty)
13641364
} else {
13651365
icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty)
1366-
}
1366+
};
1367+
ty::EarlyBinder::bind(ty::ImplTraitHeader {
1368+
trait_ref,
1369+
polarity: polarity_of_impl_item(tcx, def_id, impl_, item.span)
1370+
})
13671371
})
1368-
.map(ty::EarlyBinder::bind)
13691372
}
13701373

13711374
fn check_impl_constness(
@@ -1393,43 +1396,34 @@ fn check_impl_constness(
13931396
}))
13941397
}
13951398

1396-
fn impl_polarity(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplPolarity {
1399+
fn polarity_of_impl_item(
1400+
tcx: TyCtxt<'_>,
1401+
def_id: LocalDefId,
1402+
impl_: &hir::Impl<'_>,
1403+
span: Span,
1404+
) -> ty::ImplPolarity {
13971405
let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
1398-
let item = tcx.hir().expect_item(def_id);
1399-
match &item.kind {
1400-
hir::ItemKind::Impl(hir::Impl {
1401-
polarity: hir::ImplPolarity::Negative(span),
1402-
of_trait,
1403-
..
1404-
}) => {
1406+
match &impl_ {
1407+
hir::Impl { polarity: hir::ImplPolarity::Negative(span), of_trait, .. } => {
14051408
if is_rustc_reservation {
14061409
let span = span.to(of_trait.as_ref().map_or(*span, |t| t.path.span));
14071410
tcx.dcx().span_err(span, "reservation impls can't be negative");
14081411
}
14091412
ty::ImplPolarity::Negative
14101413
}
1411-
hir::ItemKind::Impl(hir::Impl {
1412-
polarity: hir::ImplPolarity::Positive,
1413-
of_trait: None,
1414-
..
1415-
}) => {
1414+
hir::Impl { polarity: hir::ImplPolarity::Positive, of_trait: None, .. } => {
14161415
if is_rustc_reservation {
1417-
tcx.dcx().span_err(item.span, "reservation impls can't be inherent");
1416+
tcx.dcx().span_err(span, "reservation impls can't be inherent");
14181417
}
14191418
ty::ImplPolarity::Positive
14201419
}
1421-
hir::ItemKind::Impl(hir::Impl {
1422-
polarity: hir::ImplPolarity::Positive,
1423-
of_trait: Some(_),
1424-
..
1425-
}) => {
1420+
hir::Impl { polarity: hir::ImplPolarity::Positive, of_trait: Some(_), .. } => {
14261421
if is_rustc_reservation {
14271422
ty::ImplPolarity::Reservation
14281423
} else {
14291424
ty::ImplPolarity::Positive
14301425
}
14311426
}
1432-
item => bug!("impl_polarity: {:?} not an impl", item),
14331427
}
14341428
}
14351429

compiler/rustc_hir_typeck/src/method/suggest.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -3136,12 +3136,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
31363136
if self
31373137
.tcx
31383138
.all_impls(candidate.def_id)
3139-
.filter(|imp_did| {
3140-
self.tcx.impl_polarity(*imp_did) == ty::ImplPolarity::Negative
3139+
.filter_map(|imp_did| self.tcx.impl_trait_header(imp_did))
3140+
.filter(|header| {
3141+
header.skip_binder().polarity == ty::ImplPolarity::Negative
31413142
})
3142-
.any(|imp_did| {
3143-
let imp =
3144-
self.tcx.impl_trait_ref(imp_did).unwrap().instantiate_identity();
3143+
.any(|header| {
3144+
let imp = header.instantiate_identity().trait_ref;
31453145
let imp_simp =
31463146
simplify_type(self.tcx, imp.self_ty(), TreatParams::ForLookup);
31473147
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
@@ -1962,10 +1962,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
19621962
let def_id = id.owner_id.to_def_id();
19631963

19641964
self.tables.defaultness.set_some(def_id.index, tcx.defaultness(def_id));
1965-
self.tables.impl_polarity.set_some(def_id.index, tcx.impl_polarity(def_id));
19661965

1967-
if of_trait && let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
1968-
record!(self.tables.impl_trait_ref[def_id] <- trait_ref);
1966+
if of_trait && let Some(header) = tcx.impl_trait_header(def_id) {
1967+
record!(self.tables.impl_trait_header[def_id] <- header);
1968+
let trait_ref = header.map_bound(|h| h.trait_ref);
19691969

19701970
let trait_ref = trait_ref.instantiate_identity();
19711971
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)