Skip to content

Commit 224e8f5

Browse files
committed
Auto merge of rust-lang#121123 - compiler-errors:item-assumptions, r=<try>
Split an item bounds and an item's own assumptions uwu r? `@ghost`
2 parents ee9c7c9 + 4146340 commit 224e8f5

File tree

20 files changed

+136
-46
lines changed

20 files changed

+136
-46
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
701701
.copied()
702702
.find_map(find_fn_kind_from_did),
703703
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => tcx
704-
.explicit_item_bounds(def_id)
704+
.explicit_item_own_assumptions(def_id)
705705
.iter_instantiated_copied(tcx, args)
706706
.find_map(|(clause, span)| find_fn_kind_from_did((clause, span))),
707707
ty::Closure(_, args) => match args.as_closure().kind() {

compiler/rustc_hir_analysis/src/check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ fn fn_sig_suggestion<'tcx>(
427427

428428
let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
429429
output = if let ty::Alias(_, alias_ty) = *output.kind() {
430-
tcx.explicit_item_bounds(alias_ty.def_id)
430+
tcx.explicit_item_own_assumptions(alias_ty.def_id)
431431
.iter_instantiated_copied(tcx, alias_ty.args)
432432
.find_map(|(bound, _)| bound.as_projection_clause()?.no_bound_vars()?.term.ty())
433433
.unwrap_or_else(|| {

compiler/rustc_hir_analysis/src/collect.rs

+7
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ pub fn provide(providers: &mut Providers) {
6666
type_alias_is_lazy: type_of::type_alias_is_lazy,
6767
item_bounds: item_bounds::item_bounds,
6868
explicit_item_bounds: item_bounds::explicit_item_bounds,
69+
item_own_assumptions: item_bounds::item_own_assumptions,
70+
explicit_item_own_assumptions: item_bounds::explicit_item_own_assumptions,
71+
item_non_self_assumptions: item_bounds::item_non_self_assumptions,
6972
generics_of: generics_of::generics_of,
7073
predicates_of: predicates_of::predicates_of,
7174
predicates_defined_on,
@@ -637,7 +640,9 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
637640
tcx.ensure().generics_of(def_id);
638641
tcx.ensure().predicates_of(def_id);
639642
tcx.ensure().explicit_item_bounds(def_id);
643+
tcx.ensure().explicit_item_own_assumptions(def_id);
640644
tcx.ensure().item_bounds(def_id);
645+
tcx.ensure().item_own_assumptions(def_id);
641646
}
642647

643648
hir::ItemKind::TyAlias(..) => {
@@ -693,6 +698,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
693698

694699
hir::TraitItemKind::Type(_, Some(_)) => {
695700
tcx.ensure().item_bounds(def_id);
701+
tcx.ensure().item_own_assumptions(def_id);
696702
tcx.ensure().type_of(def_id);
697703
// Account for `type T = _;`.
698704
let mut visitor = HirPlaceholderCollector::default();
@@ -702,6 +708,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
702708

703709
hir::TraitItemKind::Type(_, None) => {
704710
tcx.ensure().item_bounds(def_id);
711+
tcx.ensure().item_own_assumptions(def_id);
705712
// #74612: Visit and try to find bad placeholders
706713
// even if there is no concrete type.
707714
let mut visitor = HirPlaceholderCollector::default();

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+48-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::ItemCtxt;
22
use crate::astconv::{AstConv, PredicateFilter};
3+
use rustc_data_structures::fx::FxIndexSet;
34
use rustc_hir as hir;
45
use rustc_infer::traits::util;
56
use rustc_middle::ty::GenericArgs;
@@ -19,6 +20,7 @@ fn associated_type_bounds<'tcx>(
1920
assoc_item_def_id: LocalDefId,
2021
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
2122
span: Span,
23+
filter: PredicateFilter,
2224
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
2325
let item_ty = Ty::new_projection(
2426
tcx,
@@ -27,7 +29,7 @@ fn associated_type_bounds<'tcx>(
2729
);
2830

2931
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
30-
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All);
32+
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, filter);
3133
// Associated types are implicitly sized unless a `?Sized` bound is found
3234
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
3335

@@ -63,10 +65,11 @@ fn opaque_type_bounds<'tcx>(
6365
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
6466
item_ty: Ty<'tcx>,
6567
span: Span,
68+
filter: PredicateFilter,
6669
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
6770
ty::print::with_no_queries!({
6871
let icx = ItemCtxt::new(tcx, opaque_def_id);
69-
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All);
72+
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, filter);
7073
// Opaque types are implicitly sized unless a `?Sized` bound is found
7174
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
7275
debug!(?bounds);
@@ -78,6 +81,21 @@ fn opaque_type_bounds<'tcx>(
7881
pub(super) fn explicit_item_bounds(
7982
tcx: TyCtxt<'_>,
8083
def_id: LocalDefId,
84+
) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
85+
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::All)
86+
}
87+
88+
pub(super) fn explicit_item_own_assumptions(
89+
tcx: TyCtxt<'_>,
90+
def_id: LocalDefId,
91+
) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
92+
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::SelfOnly)
93+
}
94+
95+
pub(super) fn explicit_item_bounds_with_filter(
96+
tcx: TyCtxt<'_>,
97+
def_id: LocalDefId,
98+
filter: PredicateFilter,
8199
) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
82100
match tcx.opt_rpitit_info(def_id.to_def_id()) {
83101
// RPITIT's bounds are the same as opaque type bounds, but with
@@ -95,6 +113,7 @@ pub(super) fn explicit_item_bounds(
95113
ty::GenericArgs::identity_for_item(tcx, def_id),
96114
),
97115
item.span,
116+
filter,
98117
));
99118
}
100119
Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!(
@@ -109,15 +128,15 @@ pub(super) fn explicit_item_bounds(
109128
kind: hir::TraitItemKind::Type(bounds, _),
110129
span,
111130
..
112-
}) => associated_type_bounds(tcx, def_id, bounds, *span),
131+
}) => associated_type_bounds(tcx, def_id, bounds, *span, filter),
113132
hir::Node::Item(hir::Item {
114133
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: false, .. }),
115134
span,
116135
..
117136
}) => {
118137
let args = GenericArgs::identity_for_item(tcx, def_id);
119138
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
120-
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
139+
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
121140
}
122141
// Since RPITITs are astconv'd as projections in `ast_ty_to_ty`, when we're asking
123142
// for the item bounds of the *opaques* in a trait's default method signature, we
@@ -135,7 +154,7 @@ pub(super) fn explicit_item_bounds(
135154
let args = GenericArgs::identity_for_item(tcx, def_id);
136155
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
137156
tcx.arena.alloc_slice(
138-
&opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
157+
&opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
139158
.to_vec()
140159
.fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: fn_def_id.to_def_id() }),
141160
)
@@ -155,6 +174,30 @@ pub(super) fn item_bounds(
155174
})
156175
}
157176

177+
pub(super) fn item_own_assumptions(
178+
tcx: TyCtxt<'_>,
179+
def_id: DefId,
180+
) -> ty::EarlyBinder<&'_ ty::List<ty::Clause<'_>>> {
181+
tcx.explicit_item_own_assumptions(def_id).map_bound(|bounds| {
182+
tcx.mk_clauses_from_iter(
183+
util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)).filter_only_self(),
184+
)
185+
})
186+
}
187+
188+
pub(super) fn item_non_self_assumptions(
189+
tcx: TyCtxt<'_>,
190+
def_id: DefId,
191+
) -> ty::EarlyBinder<&'_ ty::List<ty::Clause<'_>>> {
192+
let all_bounds: FxIndexSet<_> = tcx.item_bounds(def_id).skip_binder().iter().collect();
193+
let own_bounds: FxIndexSet<_> = tcx.item_own_assumptions(def_id).skip_binder().iter().collect();
194+
if all_bounds.len() == own_bounds.len() {
195+
ty::EarlyBinder::bind(ty::List::empty())
196+
} else {
197+
ty::EarlyBinder::bind(tcx.mk_clauses_from_iter(all_bounds.difference(&own_bounds).copied()))
198+
}
199+
}
200+
158201
struct AssocTyToOpaque<'tcx> {
159202
tcx: TyCtxt<'tcx>,
160203
fn_def_id: DefId,

compiler/rustc_hir_typeck/src/_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
649649
for ty in [first_ty, second_ty] {
650650
for (clause, _) in self
651651
.tcx
652-
.explicit_item_bounds(rpit_def_id)
652+
.explicit_item_own_assumptions(rpit_def_id)
653653
.iter_instantiated_copied(self.tcx, args)
654654
{
655655
let pred = clause.kind().rebind(match clause.kind().skip_binder() {

compiler/rustc_hir_typeck/src/closure.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
329329
.deduce_closure_signature_from_predicates(
330330
expected_ty,
331331
self.tcx
332-
.explicit_item_bounds(def_id)
332+
.explicit_item_own_assumptions(def_id)
333333
.iter_instantiated_copied(self.tcx, args)
334334
.map(|(c, s)| (c.as_predicate(), s)),
335335
),
@@ -875,7 +875,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
875875
}
876876
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self
877877
.tcx
878-
.explicit_item_bounds(def_id)
878+
.explicit_item_own_assumptions(def_id)
879879
.iter_instantiated_copied(self.tcx, args)
880880
.find_map(|(p, s)| get_future_output(p.as_predicate(), s))?,
881881
ty::Error(_) => return Some(ret_ty),

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -400,8 +400,10 @@ impl<'tcx> InferCtxt<'tcx> {
400400
let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
401401
let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
402402

403-
self.tcx.explicit_item_bounds(def_id).iter_instantiated_copied(self.tcx, args).find_map(
404-
|(predicate, _)| {
403+
self.tcx
404+
.explicit_item_own_assumptions(def_id)
405+
.iter_instantiated_copied(self.tcx, args)
406+
.find_map(|(predicate, _)| {
405407
predicate
406408
.kind()
407409
.map_bound(|kind| match kind {
@@ -414,8 +416,7 @@ impl<'tcx> InferCtxt<'tcx> {
414416
})
415417
.no_bound_vars()
416418
.flatten()
417-
},
418-
)
419+
})
419420
}
420421
}
421422

compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -299,17 +299,19 @@ impl<T> Trait<T> for X {
299299
}
300300
(ty::Dynamic(t, _, ty::DynKind::Dyn), ty::Alias(ty::Opaque, alias))
301301
if let Some(def_id) = t.principal_def_id()
302-
&& tcx.explicit_item_bounds(alias.def_id).skip_binder().iter().any(
303-
|(pred, _span)| match pred.kind().skip_binder() {
302+
&& tcx
303+
.explicit_item_own_assumptions(alias.def_id)
304+
.skip_binder()
305+
.iter()
306+
.any(|(pred, _span)| match pred.kind().skip_binder() {
304307
ty::ClauseKind::Trait(trait_predicate)
305308
if trait_predicate.polarity
306309
== ty::ImplPolarity::Positive =>
307310
{
308311
trait_predicate.def_id() == def_id
309312
}
310313
_ => false,
311-
},
312-
) =>
314+
}) =>
313315
{
314316
diag.help(format!(
315317
"you can box the `{}` to coerce it to `Box<{}>`, but you'll have to \
@@ -412,7 +414,7 @@ impl<T> Trait<T> for X {
412414
ty::Alias(..) => values.expected,
413415
_ => values.found,
414416
};
415-
let preds = tcx.explicit_item_bounds(opaque_ty.def_id);
417+
let preds = tcx.explicit_item_own_assumptions(opaque_ty.def_id);
416418
for (pred, _span) in preds.skip_binder() {
417419
let ty::ClauseKind::Trait(trait_predicate) = pred.kind().skip_binder()
418420
else {

compiler/rustc_infer/src/infer/outlives/verify.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
300300
alias_ty: ty::AliasTy<'tcx>,
301301
) -> impl Iterator<Item = ty::Region<'tcx>> {
302302
let tcx = self.tcx;
303-
let bounds = tcx.item_bounds(alias_ty.def_id);
303+
let bounds = tcx.item_own_assumptions(alias_ty.def_id);
304304
trace!("{:#?}", bounds.skip_binder());
305305
bounds
306306
.iter_instantiated(tcx, alias_ty.args)

compiler/rustc_lint/src/unused.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,9 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
294294
ty::Alias(ty::Opaque | ty::Projection, ty::AliasTy { def_id: def, .. }) => {
295295
elaborate(
296296
cx.tcx,
297-
cx.tcx.explicit_item_bounds(def).instantiate_identity_iter_copied(),
297+
cx.tcx
298+
.explicit_item_own_assumptions(def)
299+
.instantiate_identity_iter_copied(),
298300
)
299301
// We only care about self bounds for the impl-trait
300302
.filter_only_self()

compiler/rustc_metadata/src/rmeta/decoder.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,20 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
10471047
ty::EarlyBinder::bind(&*output)
10481048
}
10491049

1050+
fn get_explicit_item_own_assumptions(
1051+
self,
1052+
index: DefIndex,
1053+
tcx: TyCtxt<'tcx>,
1054+
) -> ty::EarlyBinder<&'tcx [(ty::Clause<'tcx>, Span)]> {
1055+
let lazy = self.root.tables.explicit_item_own_assumptions.get(self, index);
1056+
let output = if lazy.is_default() {
1057+
&mut []
1058+
} else {
1059+
tcx.arena.alloc_from_iter(lazy.decode((self, tcx)))
1060+
};
1061+
ty::EarlyBinder::bind(&*output)
1062+
}
1063+
10501064
fn get_variant(
10511065
self,
10521066
kind: DefKind,

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

+1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ impl IntoArgs for (CrateNum, SimplifiedType) {
206206

207207
provide! { tcx, def_id, other, cdata,
208208
explicit_item_bounds => { cdata.get_explicit_item_bounds(def_id.index, tcx) }
209+
explicit_item_own_assumptions => { cdata.get_explicit_item_own_assumptions(def_id.index, tcx) }
209210
explicit_predicates_of => { table }
210211
generics_of => { table }
211212
inferred_outlives_of => { table_defaulted_array }

compiler/rustc_metadata/src/rmeta/encoder.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14701470
}
14711471
if let DefKind::OpaqueTy = def_kind {
14721472
self.encode_explicit_item_bounds(def_id);
1473+
self.encode_explicit_item_own_assumptions(def_id);
14731474
self.tables
14741475
.is_type_alias_impl_trait
14751476
.set(def_id.index, self.tcx.is_type_alias_impl_trait(def_id));
@@ -1578,6 +1579,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
15781579
record_defaulted_array!(self.tables.explicit_item_bounds[def_id] <- bounds);
15791580
}
15801581

1582+
fn encode_explicit_item_own_assumptions(&mut self, def_id: DefId) {
1583+
debug!("EncodeContext::encode_explicit_item_own_assumptions({:?})", def_id);
1584+
let bounds = self.tcx.explicit_item_own_assumptions(def_id).skip_binder();
1585+
record_defaulted_array!(self.tables.explicit_item_own_assumptions[def_id] <- bounds);
1586+
}
1587+
15811588
#[instrument(level = "debug", skip(self))]
15821589
fn encode_info_for_assoc_item(&mut self, def_id: DefId) {
15831590
let tcx = self.tcx;
@@ -1590,6 +1597,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
15901597
AssocItemContainer::TraitContainer => {
15911598
if let ty::AssocKind::Type = item.kind {
15921599
self.encode_explicit_item_bounds(def_id);
1600+
self.encode_explicit_item_own_assumptions(def_id);
15931601
}
15941602
}
15951603
AssocItemContainer::ImplContainer => {

compiler/rustc_metadata/src/rmeta/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ define_tables! {
387387
// corresponding DefPathHash.
388388
def_path_hashes: Table<DefIndex, u64>,
389389
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
390+
explicit_item_own_assumptions: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
390391
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
391392
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
392393
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,

compiler/rustc_middle/src/query/mod.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,12 @@ rustc_queries! {
372372
desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
373373
cache_on_disk_if { key.is_local() }
374374
separate_provide_extern
375-
feedable
375+
}
376+
377+
query explicit_item_own_assumptions(key: DefId) -> ty::EarlyBinder<&'tcx [(ty::Clause<'tcx>, Span)]> {
378+
desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
379+
cache_on_disk_if { key.is_local() }
380+
separate_provide_extern
376381
}
377382

378383
/// Elaborated version of the predicates from `explicit_item_bounds`.
@@ -399,6 +404,14 @@ rustc_queries! {
399404
desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) }
400405
}
401406

407+
query item_own_assumptions(key: DefId) -> ty::EarlyBinder<&'tcx ty::List<ty::Clause<'tcx>>> {
408+
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
409+
}
410+
411+
query item_non_self_assumptions(key: DefId) -> ty::EarlyBinder<&'tcx ty::List<ty::Clause<'tcx>>> {
412+
desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) }
413+
}
414+
402415
/// Look up all native libraries this crate depends on.
403416
/// These are assembled from the following places:
404417
/// - `extern` blocks (depending on their `link` attributes)

compiler/rustc_middle/src/ty/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1763,7 +1763,7 @@ impl<'tcx> TyCtxt<'tcx> {
17631763
let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false };
17641764
let future_trait = self.require_lang_item(LangItem::Future, None);
17651765

1766-
self.explicit_item_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
1766+
self.explicit_item_own_assumptions(def_id).skip_binder().iter().any(|&(predicate, _)| {
17671767
let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
17681768
return false;
17691769
};

0 commit comments

Comments
 (0)