Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 513eeb3

Browse files
committedMar 13, 2025·
Implement non-lifetime binder lowering
1 parent 88e6065 commit 513eeb3

File tree

11 files changed

+258
-114
lines changed

11 files changed

+258
-114
lines changed
 

‎compiler/rustc_ast_lowering/src/item.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1753,6 +1753,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
17531753
bounded_ty: self.arena.alloc(bounded_ty),
17541754
bounds,
17551755
bound_generic_params: &[],
1756+
bound_assumptions: &[],
17561757
origin,
17571758
})
17581759
}
@@ -1782,6 +1783,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
17821783
}) => hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
17831784
bound_generic_params: self
17841785
.lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder),
1786+
bound_assumptions: self.arena.alloc_from_iter(
1787+
bound_generic_params.iter().filter_map(|param| {
1788+
self.lower_generic_bound_predicate(
1789+
param.ident,
1790+
param.id,
1791+
&param.kind,
1792+
&param.bounds,
1793+
param.colon_span,
1794+
span,
1795+
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1796+
PredicateOrigin::GenericParam,
1797+
)
1798+
}),
1799+
),
17851800
bounded_ty: self
17861801
.lower_ty(bounded_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
17871802
bounds: self.lower_param_bounds(

‎compiler/rustc_ast_lowering/src/lib.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
5555
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
5656
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
5757
use rustc_hir::{
58-
self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem, ParamName, TraitCandidate,
58+
self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem, ParamName, PredicateOrigin,
59+
TraitCandidate,
5960
};
6061
use rustc_index::{Idx, IndexSlice, IndexVec};
6162
use rustc_macros::extension;
@@ -1734,6 +1735,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17341735

17351736
hir::GenericBound::Trait(hir::PolyTraitRef {
17361737
bound_generic_params: &[],
1738+
bound_assumptions: &[],
17371739
modifiers: hir::TraitBoundModifiers::NONE,
17381740
trait_ref: hir::TraitRef {
17391741
path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
@@ -1947,12 +1949,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
19471949
p: &PolyTraitRef,
19481950
itctx: ImplTraitContext,
19491951
) -> hir::PolyTraitRef<'hir> {
1952+
let bound_assumptions =
1953+
self.arena.alloc_from_iter(p.bound_generic_params.iter().filter_map(|param| {
1954+
self.lower_generic_bound_predicate(
1955+
param.ident,
1956+
param.id,
1957+
&param.kind,
1958+
&param.bounds,
1959+
param.colon_span,
1960+
p.span,
1961+
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1962+
PredicateOrigin::GenericParam,
1963+
)
1964+
}));
19501965
let bound_generic_params =
19511966
self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
19521967
let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
19531968
let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
19541969
hir::PolyTraitRef {
19551970
bound_generic_params,
1971+
bound_assumptions,
19561972
modifiers,
19571973
trait_ref,
19581974
span: self.lower_span(p.span),
@@ -2361,6 +2377,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23612377
Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
23622378
let principal = hir::PolyTraitRef {
23632379
bound_generic_params: &[],
2380+
bound_assumptions: &[],
23642381
modifiers: hir::TraitBoundModifiers::NONE,
23652382
trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
23662383
span: self.lower_span(span),

‎compiler/rustc_hir/src/hir.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,8 @@ pub struct WhereBoundPredicate<'hir> {
951951
pub origin: PredicateOrigin,
952952
/// Any generics from a `for` binding.
953953
pub bound_generic_params: &'hir [GenericParam<'hir>],
954+
/// The `'a + Trait` in `for<T: 'a + Trait> ...`
955+
pub bound_assumptions: &'hir [WherePredicate<'hir>],
954956
/// The type being bounded.
955957
pub bounded_ty: &'hir Ty<'hir>,
956958
/// Trait and lifetime bounds (e.g., `Clone + Send + 'static`).
@@ -3793,6 +3795,9 @@ pub struct PolyTraitRef<'hir> {
37933795
/// The `'a` in `for<'a> Foo<&'a T>`.
37943796
pub bound_generic_params: &'hir [GenericParam<'hir>],
37953797

3798+
/// The `'a + Trait` in `for<T: 'a + Trait> ...`
3799+
pub bound_assumptions: &'hir [WherePredicate<'hir>],
3800+
37963801
/// The constness and polarity of the trait ref.
37973802
///
37983803
/// The `async` modifier is lowered directly into a different trait for now.
@@ -4758,7 +4763,7 @@ mod size_asserts {
47584763
static_assert_size!(ForeignItem<'_>, 88);
47594764
static_assert_size!(ForeignItemKind<'_>, 56);
47604765
static_assert_size!(GenericArg<'_>, 16);
4761-
static_assert_size!(GenericBound<'_>, 64);
4766+
static_assert_size!(GenericBound<'_>, 80);
47624767
static_assert_size!(Generics<'_>, 56);
47634768
static_assert_size!(Impl<'_>, 80);
47644769
static_assert_size!(ImplItem<'_>, 88);

‎compiler/rustc_hir/src/intravisit.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1065,10 +1065,12 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
10651065
ref bounded_ty,
10661066
bounds,
10671067
bound_generic_params,
1068+
bound_assumptions,
10681069
origin: _,
10691070
}) => {
10701071
try_visit!(visitor.visit_ty_unambig(bounded_ty));
10711072
walk_list!(visitor, visit_param_bound, bounds);
1073+
walk_list!(visitor, visit_where_predicate, bound_assumptions);
10721074
walk_list!(visitor, visit_generic_param, bound_generic_params);
10731075
}
10741076
WherePredicateKind::RegionPredicate(WhereRegionPredicate {
@@ -1277,6 +1279,7 @@ pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(
12771279
trait_ref: &'v PolyTraitRef<'v>,
12781280
) -> V::Result {
12791281
walk_list!(visitor, visit_generic_param, trait_ref.bound_generic_params);
1282+
walk_list!(visitor, visit_where_predicate, trait_ref.bound_assumptions);
12801283
visitor.visit_trait_ref(&trait_ref.trait_ref)
12811284
}
12821285

‎compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,14 @@ fn associated_type_bounds<'tcx>(
3838

3939
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
4040
let mut bounds = Vec::new();
41-
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
41+
icx.lowerer().lower_bounds(
42+
item_ty,
43+
hir_bounds,
44+
&mut bounds,
45+
ty::List::empty(),
46+
ty::ListWithCachedTypeInfo::empty(),
47+
filter,
48+
);
4249
// Associated types are implicitly sized unless a `?Sized` bound is found
4350
match filter {
4451
PredicateFilter::All
@@ -327,7 +334,14 @@ fn opaque_type_bounds<'tcx>(
327334
ty::print::with_reduced_queries!({
328335
let icx = ItemCtxt::new(tcx, opaque_def_id);
329336
let mut bounds = Vec::new();
330-
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
337+
icx.lowerer().lower_bounds(
338+
item_ty,
339+
hir_bounds,
340+
&mut bounds,
341+
ty::List::empty(),
342+
ty::ListWithCachedTypeInfo::empty(),
343+
filter,
344+
);
331345
// Opaque types are implicitly sized unless a `?Sized` bound is found
332346
match filter {
333347
PredicateFilter::All

‎compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+42-102
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ use rustc_middle::ty::{
1010
};
1111
use rustc_middle::{bug, span_bug};
1212
use rustc_span::{DUMMY_SP, Ident, Span};
13-
use tracing::{debug, instrument, trace};
13+
use tracing::{debug, instrument};
1414

1515
use super::item_bounds::explicit_item_bounds_with_filter;
1616
use crate::collect::ItemCtxt;
1717
use crate::constrained_generic_params as cgp;
1818
use crate::delegation::inherit_predicates_for_delegation_item;
19-
use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter, RegionInferReason};
19+
use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter};
2020

2121
/// Returns a list of all type predicates (explicit and implicit) for the definition with
2222
/// ID `def_id`. This includes all predicates returned by `explicit_predicates_of`, plus
@@ -183,6 +183,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
183183
self_bounds,
184184
&mut bounds,
185185
ty::List::empty(),
186+
ty::ListWithCachedTypeInfo::empty(),
186187
PredicateFilter::All,
187188
);
188189
predicates.extend(bounds);
@@ -200,105 +201,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
200201
predicates.insert((trait_ref.upcast(tcx), tcx.def_span(def_id)));
201202
}
202203

203-
// Add implicit predicates that should be treated as if the user has written them,
204-
// including the implicit `T: Sized` for all generic parameters, and `ConstArgHasType`
205-
// for const params.
206-
for param in hir_generics.params {
207-
match param.kind {
208-
GenericParamKind::Lifetime { .. } => (),
209-
GenericParamKind::Type { .. } => {
210-
let param_ty = icx.lowerer().lower_ty_param(param.hir_id);
211-
let mut bounds = Vec::new();
212-
// Params are implicitly sized unless a `?Sized` bound is found
213-
icx.lowerer().add_sized_bound(
214-
&mut bounds,
215-
param_ty,
216-
&[],
217-
Some((param.def_id, hir_generics.predicates)),
218-
param.span,
219-
);
220-
trace!(?bounds);
221-
predicates.extend(bounds);
222-
trace!(?predicates);
223-
}
224-
hir::GenericParamKind::Const { .. } => {
225-
let param_def_id = param.def_id.to_def_id();
226-
let ct_ty = tcx.type_of(param_def_id).instantiate_identity();
227-
let ct = icx.lowerer().lower_const_param(param_def_id, param.hir_id);
228-
predicates
229-
.insert((ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx), param.span));
230-
}
231-
}
232-
}
233-
234-
trace!(?predicates);
235-
// Add inline `<T: Foo>` bounds and bounds in the where clause.
236-
for predicate in hir_generics.predicates {
237-
match predicate.kind {
238-
hir::WherePredicateKind::BoundPredicate(bound_pred) => {
239-
let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
240-
241-
let bound_vars = tcx.late_bound_vars(predicate.hir_id);
242-
// Keep the type around in a dummy predicate, in case of no bounds.
243-
// That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
244-
// is still checked for WF.
245-
if bound_pred.bounds.is_empty() {
246-
if let ty::Param(_) = ty.kind() {
247-
// This is a `where T:`, which can be in the HIR from the
248-
// transformation that moves `?Sized` to `T`'s declaration.
249-
// We can skip the predicate because type parameters are
250-
// trivially WF, but also we *should*, to avoid exposing
251-
// users who never wrote `where Type:,` themselves, to
252-
// compiler/tooling bugs from not handling WF predicates.
253-
} else {
254-
let span = bound_pred.bounded_ty.span;
255-
let predicate = ty::Binder::bind_with_vars(
256-
ty::ClauseKind::WellFormed(ty.into()),
257-
bound_vars,
258-
);
259-
predicates.insert((predicate.upcast(tcx), span));
260-
}
261-
}
262-
263-
let mut bounds = Vec::new();
264-
icx.lowerer().lower_bounds(
265-
ty,
266-
bound_pred.bounds,
267-
&mut bounds,
268-
bound_vars,
269-
PredicateFilter::All,
270-
);
271-
predicates.extend(bounds);
272-
}
273-
274-
hir::WherePredicateKind::RegionPredicate(region_pred) => {
275-
let r1 = icx
276-
.lowerer()
277-
.lower_lifetime(region_pred.lifetime, RegionInferReason::RegionPredicate);
278-
predicates.extend(region_pred.bounds.iter().map(|bound| {
279-
let (r2, span) = match bound {
280-
hir::GenericBound::Outlives(lt) => (
281-
icx.lowerer().lower_lifetime(lt, RegionInferReason::RegionPredicate),
282-
lt.ident.span,
283-
),
284-
bound => {
285-
span_bug!(
286-
bound.span(),
287-
"lifetime param bounds must be outlives, but found {bound:?}"
288-
)
289-
}
290-
};
291-
let pred =
292-
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2)).upcast(tcx);
293-
(pred, span)
294-
}))
295-
}
296-
297-
hir::WherePredicateKind::EqPredicate(..) => {
298-
// FIXME(#20041)
299-
}
300-
}
301-
}
204+
icx.lowerer().lower_where_predicates(
205+
hir_generics.params,
206+
hir_generics.predicates,
207+
&mut predicates,
208+
);
302209

303210
if tcx.features().generic_const_exprs() {
304211
predicates.extend(const_evaluatable_predicates_of(tcx, def_id, &predicates));
@@ -623,7 +530,14 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
623530

624531
let self_param_ty = tcx.types.self_param;
625532
let mut bounds = Vec::new();
626-
icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter);
533+
icx.lowerer().lower_bounds(
534+
self_param_ty,
535+
superbounds,
536+
&mut bounds,
537+
ty::List::empty(),
538+
ty::ListWithCachedTypeInfo::empty(),
539+
filter,
540+
);
627541

628542
let where_bounds_that_match =
629543
icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter);
@@ -923,12 +837,24 @@ impl<'tcx> ItemCtxt<'tcx> {
923837

924838
let bound_ty = self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty);
925839

840+
let mut bound_assumptions = FxIndexSet::default();
841+
if self.tcx.features().non_lifetime_binders() {
842+
self.lowerer().lower_where_predicates(
843+
predicate.bound_generic_params,
844+
predicate.bound_assumptions,
845+
&mut bound_assumptions,
846+
);
847+
}
848+
let bound_assumptions =
849+
self.tcx().mk_clauses_from_iter(bound_assumptions.into_iter().map(|(c, _)| c));
850+
926851
let bound_vars = self.tcx.late_bound_vars(hir_id);
927852
self.lowerer().lower_bounds(
928853
bound_ty,
929854
predicate.bounds,
930855
&mut bounds,
931856
bound_vars,
857+
bound_assumptions,
932858
filter,
933859
);
934860
}
@@ -1002,12 +928,25 @@ pub(super) fn const_conditions<'tcx>(
1002928
match pred.kind {
1003929
hir::WherePredicateKind::BoundPredicate(bound_pred) => {
1004930
let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
931+
932+
let mut bound_assumptions = FxIndexSet::default();
933+
if tcx.features().non_lifetime_binders() {
934+
icx.lowerer().lower_where_predicates(
935+
bound_pred.bound_generic_params,
936+
bound_pred.bound_assumptions,
937+
&mut bound_assumptions,
938+
);
939+
}
940+
let bound_assumptions =
941+
icx.tcx().mk_clauses_from_iter(bound_assumptions.into_iter().map(|(c, _)| c));
942+
1005943
let bound_vars = tcx.late_bound_vars(pred.hir_id);
1006944
icx.lowerer().lower_bounds(
1007945
ty,
1008946
bound_pred.bounds.iter(),
1009947
&mut bounds,
1010948
bound_vars,
949+
bound_assumptions,
1011950
PredicateFilter::ConstIfConst,
1012951
);
1013952
}
@@ -1028,6 +967,7 @@ pub(super) fn const_conditions<'tcx>(
1028967
supertraits,
1029968
&mut bounds,
1030969
ty::List::empty(),
970+
ty::ListWithCachedTypeInfo::empty(),
1031971
PredicateFilter::ConstIfConst,
1032972
);
1033973
}

‎compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+3
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
403403
};
404404
self.with(scope, |this| {
405405
walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
406+
walk_list!(this, visit_where_predicate, trait_ref.bound_assumptions);
406407
this.visit_trait_ref(&trait_ref.trait_ref);
407408
});
408409
}
@@ -939,6 +940,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
939940
bounded_ty,
940941
bounds,
941942
bound_generic_params,
943+
bound_assumptions,
942944
origin,
943945
..
944946
}) => {
@@ -973,6 +975,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
973975
self.with(scope, |this| {
974976
walk_list!(this, visit_generic_param, bound_generic_params);
975977
this.visit_ty_unambig(bounded_ty);
978+
walk_list!(this, visit_where_predicate, bound_assumptions);
976979
walk_list!(this, visit_param_bound, bounds);
977980
})
978981
}

‎compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

+149-5
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
use rustc_hir::HirId;
88
use rustc_hir::def::{DefKind, Res};
99
use rustc_hir::def_id::{DefId, LocalDefId};
10-
use rustc_middle::bug;
1110
use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt, Upcast};
11+
use rustc_middle::{bug, span_bug};
1212
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
1313
use rustc_trait_selection::traits;
1414
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
1515
use smallvec::SmallVec;
16-
use tracing::{debug, instrument};
16+
use tracing::{debug, instrument, trace};
1717

1818
use super::errors::GenericsArgsErrExtend;
1919
use crate::errors;
@@ -22,6 +22,129 @@
2222
};
2323

2424
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
25+
pub(crate) fn lower_where_predicates(
26+
&self,
27+
params: &[hir::GenericParam<'tcx>],
28+
hir_predicates: &[hir::WherePredicate<'tcx>],
29+
predicates: &mut FxIndexSet<(ty::Clause<'tcx>, Span)>,
30+
) {
31+
let tcx = self.tcx();
32+
// Add implicit predicates that should be treated as if the user has written them,
33+
// including the implicit `T: Sized` for all generic parameters, and `ConstArgHasType`
34+
// for const params.
35+
for param in params {
36+
match param.kind {
37+
hir::GenericParamKind::Lifetime { .. } => (),
38+
hir::GenericParamKind::Type { .. } => {
39+
// TODO:
40+
let param_ty =
41+
ty::fold::shift_vars(self.tcx(), self.lower_ty_param(param.hir_id), 1);
42+
let mut bounds = Vec::new();
43+
// Params are implicitly sized unless a `?Sized` bound is found
44+
self.add_sized_bound(
45+
&mut bounds,
46+
param_ty,
47+
&[],
48+
Some((param.def_id, hir_predicates)),
49+
param.span,
50+
);
51+
trace!(?bounds);
52+
predicates.extend(bounds);
53+
trace!(?predicates);
54+
}
55+
hir::GenericParamKind::Const { .. } => {
56+
let param_def_id = param.def_id.to_def_id();
57+
let ct_ty = tcx.type_of(param_def_id).instantiate_identity();
58+
let ct = self.lower_const_param(param_def_id, param.hir_id);
59+
predicates.insert((
60+
ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx),
61+
param.span,
62+
));
63+
}
64+
}
65+
}
66+
67+
// Add inline `<T: Foo>` bounds and bounds in the where clause.
68+
for predicate in hir_predicates {
69+
match predicate.kind {
70+
hir::WherePredicateKind::BoundPredicate(bound_pred) => {
71+
let ty = self.lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
72+
73+
let mut bound_assumptions = FxIndexSet::default();
74+
if self.tcx().features().non_lifetime_binders() {
75+
self.lower_where_predicates(
76+
bound_pred.bound_generic_params,
77+
bound_pred.bound_assumptions,
78+
&mut bound_assumptions,
79+
);
80+
}
81+
let bound_assumptions = self.tcx().mk_clauses_from_iter(
82+
bound_assumptions.into_iter().map(|(clause, _)| clause),
83+
);
84+
85+
let bound_vars = tcx.late_bound_vars(predicate.hir_id);
86+
// Keep the type around in a dummy predicate, in case of no bounds.
87+
// That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
88+
// is still checked for WF.
89+
if bound_pred.bounds.is_empty() {
90+
if let ty::Param(_) = ty.kind() {
91+
// This is a `where T:`, which can be in the HIR from the
92+
// transformation that moves `?Sized` to `T`'s declaration.
93+
// We can skip the predicate because type parameters are
94+
// trivially WF, but also we *should*, to avoid exposing
95+
// users who never wrote `where Type:,` themselves, to
96+
// compiler/tooling bugs from not handling WF predicates.
97+
} else {
98+
let span = bound_pred.bounded_ty.span;
99+
let predicate = ty::Binder::bind_with_vars(
100+
ty::ClauseKind::WellFormed(ty.into()),
101+
bound_vars,
102+
);
103+
predicates.insert((predicate.upcast(tcx), span));
104+
}
105+
}
106+
107+
let mut bounds = Vec::new();
108+
self.lower_bounds(
109+
ty,
110+
bound_pred.bounds,
111+
&mut bounds,
112+
bound_vars,
113+
bound_assumptions,
114+
PredicateFilter::All,
115+
);
116+
predicates.extend(bounds);
117+
}
118+
119+
hir::WherePredicateKind::RegionPredicate(region_pred) => {
120+
let r1 = self
121+
.lower_lifetime(region_pred.lifetime, RegionInferReason::RegionPredicate);
122+
predicates.extend(region_pred.bounds.iter().map(|bound| {
123+
let (r2, span) = match bound {
124+
hir::GenericBound::Outlives(lt) => (
125+
self.lower_lifetime(lt, RegionInferReason::RegionPredicate),
126+
lt.ident.span,
127+
),
128+
bound => {
129+
span_bug!(
130+
bound.span(),
131+
"lifetime param bounds must be outlives, but found {bound:?}"
132+
)
133+
}
134+
};
135+
let pred = ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2))
136+
.upcast(tcx);
137+
(pred, span)
138+
}))
139+
}
140+
141+
hir::WherePredicateKind::EqPredicate(..) => {
142+
// FIXME(#20041)
143+
}
144+
}
145+
}
146+
}
147+
25148
/// Add a `Sized` bound to the `bounds` if appropriate.
26149
///
27150
/// Doesn't add the bound if the HIR bounds contain any of `Sized`, `?Sized` or `!Sized`.
@@ -30,7 +153,7 @@
30153
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
31154
self_ty: Ty<'tcx>,
32155
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
33-
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
156+
self_ty_where_predicates: Option<(LocalDefId, &[hir::WherePredicate<'tcx>])>,
34157
span: Span,
35158
) {
36159
let tcx = self.tcx();
@@ -115,7 +238,10 @@
115238
} else if let Some(sized_def_id) = sized_def_id {
116239
// There was no `?Sized`, `!Sized` or explicit `Sized` bound;
117240
// add `Sized` if it's available.
118-
let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [self_ty]);
241+
let trait_ref = ty::Binder::bind_with_vars(
242+
ty::TraitRef::new(tcx, sized_def_id, [self_ty]),
243+
ty::List::empty(),
244+
);
119245
// Preferable to put this obligation first, since we report better errors for sized ambiguity.
120246
bounds.insert(0, (trait_ref.upcast(tcx), span));
121247
}
@@ -149,6 +275,7 @@
149275
hir_bounds: I,
150276
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
151277
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
278+
bound_assumptions: ty::Clauses<'tcx>,
152279
predicate_filter: PredicateFilter,
153280
) where
154281
'tcx: 'hir,
@@ -170,12 +297,27 @@
170297
match hir_bound {
171298
hir::GenericBound::Trait(poly_trait_ref) => {
172299
let hir::TraitBoundModifiers { constness, polarity } = poly_trait_ref.modifiers;
300+
301+
let mut additional_bound_assumptions = FxIndexSet::default();
302+
if self.tcx().features().non_lifetime_binders() {
303+
self.lower_where_predicates(
304+
poly_trait_ref.bound_generic_params,
305+
poly_trait_ref.bound_assumptions,
306+
&mut additional_bound_assumptions,
307+
);
308+
}
309+
let bound_assumptions =
310+
self.tcx().mk_clauses_from_iter(bound_assumptions.into_iter().chain(
311+
additional_bound_assumptions.into_iter().map(|(clause, _)| clause),
312+
));
313+
173314
let _ = self.lower_poly_trait_ref(
174315
&poly_trait_ref.trait_ref,
175316
poly_trait_ref.span,
176317
constness,
177318
polarity,
178319
param_ty,
320+
bound_assumptions,
179321
bounds,
180322
predicate_filter,
181323
);
@@ -190,9 +332,10 @@
190332
}
191333

192334
let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound);
193-
let bound = ty::Binder::bind_with_vars(
335+
let bound = ty::Binder::bind_with_vars_and_clauses(
194336
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(param_ty, region)),
195337
bound_vars,
338+
bound_assumptions,
196339
);
197340
bounds.push((bound.upcast(self.tcx()), lifetime.ident.span));
198341
}
@@ -419,6 +562,7 @@
419562
hir_bounds,
420563
bounds,
421564
projection_ty.bound_vars(),
565+
projection_ty.skip_binder_with_clauses().1,
422566
predicate_filter,
423567
);
424568
}

‎compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
5151
hir::BoundConstness::Never,
5252
hir::BoundPolarity::Positive,
5353
dummy_self,
54+
ty::ListWithCachedTypeInfo::empty(),
5455
&mut user_written_bounds,
5556
PredicateFilter::SelfOnly,
5657
) {

‎compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
736736
constness: hir::BoundConstness,
737737
polarity: hir::BoundPolarity,
738738
self_ty: Ty<'tcx>,
739+
bound_assumptions: ty::Clauses<'tcx>,
739740
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
740741
predicate_filter: PredicateFilter,
741742
) -> GenericArgCountResult {
@@ -760,9 +761,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
760761
let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
761762
debug!(?bound_vars);
762763

763-
let poly_trait_ref = ty::Binder::bind_with_vars(
764+
let poly_trait_ref = ty::Binder::bind_with_vars_and_clauses(
764765
ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args),
765766
bound_vars,
767+
bound_assumptions,
766768
);
767769

768770
debug!(?poly_trait_ref);
@@ -2649,6 +2651,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
26492651
hir_bounds.iter(),
26502652
&mut bounds,
26512653
ty::List::empty(),
2654+
ty::ListWithCachedTypeInfo::empty(),
26522655
PredicateFilter::All,
26532656
);
26542657
self.register_trait_ascription_bounds(bounds, hir_ty.hir_id, hir_ty.span);

‎compiler/rustc_type_ir/src/binder.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,7 @@ impl<I: Interner, T> Binder<I, T> {
284284
where
285285
T: TypeVisitable<I>,
286286
{
287-
// `self.value` is equivalent to `self.skip_binder()`
288-
if self.value.has_escaping_bound_vars() && self.clauses.is_empty() {
287+
if self.value.has_escaping_bound_vars() || !self.clauses.is_empty() {
289288
None
290289
} else {
291290
Some(self.skip_binder())

0 commit comments

Comments
 (0)
Please sign in to comment.