Skip to content

Commit 69d0dca

Browse files
Implement non-lifetime binder lowering
1 parent 516814c commit 69d0dca

File tree

11 files changed

+260
-119
lines changed

11 files changed

+260
-119
lines changed

compiler/rustc_ast_lowering/src/item.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
17931793
bounded_ty: self.arena.alloc(bounded_ty),
17941794
bounds,
17951795
bound_generic_params: &[],
1796+
bound_assumptions: &[],
17961797
origin,
17971798
})
17981799
}
@@ -1821,6 +1822,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
18211822
}) => hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
18221823
bound_generic_params: self
18231824
.lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder),
1825+
bound_assumptions: self.arena.alloc_from_iter(
1826+
bound_generic_params.iter().filter_map(|param| {
1827+
self.lower_generic_bound_predicate(
1828+
param.ident,
1829+
param.id,
1830+
&param.kind,
1831+
&param.bounds,
1832+
param.colon_span,
1833+
span,
1834+
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1835+
PredicateOrigin::GenericParam,
1836+
)
1837+
}),
1838+
),
18241839
bounded_ty: self
18251840
.lower_ty(bounded_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
18261841
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;
@@ -1741,6 +1742,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17411742

17421743
hir::GenericBound::Trait(hir::PolyTraitRef {
17431744
bound_generic_params: &[],
1745+
bound_assumptions: &[],
17441746
modifiers: hir::TraitBoundModifiers::NONE,
17451747
trait_ref: hir::TraitRef {
17461748
path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
@@ -1942,12 +1944,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
19421944
p: &PolyTraitRef,
19431945
itctx: ImplTraitContext,
19441946
) -> hir::PolyTraitRef<'hir> {
1947+
let bound_assumptions =
1948+
self.arena.alloc_from_iter(p.bound_generic_params.iter().filter_map(|param| {
1949+
self.lower_generic_bound_predicate(
1950+
param.ident,
1951+
param.id,
1952+
&param.kind,
1953+
&param.bounds,
1954+
param.colon_span,
1955+
p.span,
1956+
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1957+
PredicateOrigin::GenericParam,
1958+
)
1959+
}));
19451960
let bound_generic_params =
19461961
self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
19471962
let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
19481963
let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
19491964
hir::PolyTraitRef {
19501965
bound_generic_params,
1966+
bound_assumptions,
19511967
modifiers,
19521968
trait_ref,
19531969
span: self.lower_span(p.span),
@@ -2356,6 +2372,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23562372
Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
23572373
let principal = hir::PolyTraitRef {
23582374
bound_generic_params: &[],
2375+
bound_assumptions: &[],
23592376
modifiers: hir::TraitBoundModifiers::NONE,
23602377
trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
23612378
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`).
@@ -3799,6 +3801,9 @@ pub struct PolyTraitRef<'hir> {
37993801
/// The `'a` in `for<'a> Foo<&'a T>`.
38003802
pub bound_generic_params: &'hir [GenericParam<'hir>],
38013803

3804+
/// The `'a + Trait` in `for<T: 'a + Trait> ...`
3805+
pub bound_assumptions: &'hir [WherePredicate<'hir>],
3806+
38023807
/// The constness and polarity of the trait ref.
38033808
///
38043809
/// The `async` modifier is lowered directly into a different trait for now.
@@ -4797,7 +4802,7 @@ mod size_asserts {
47974802
static_assert_size!(ForeignItem<'_>, 88);
47984803
static_assert_size!(ForeignItemKind<'_>, 56);
47994804
static_assert_size!(GenericArg<'_>, 16);
4800-
static_assert_size!(GenericBound<'_>, 64);
4805+
static_assert_size!(GenericBound<'_>, 80);
48014806
static_assert_size!(Generics<'_>, 56);
48024807
static_assert_size!(Impl<'_>, 80);
48034808
static_assert_size!(ImplItem<'_>, 88);

compiler/rustc_hir/src/intravisit.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1080,10 +1080,12 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
10801080
ref bounded_ty,
10811081
bounds,
10821082
bound_generic_params,
1083+
bound_assumptions,
10831084
origin: _,
10841085
}) => {
10851086
try_visit!(visitor.visit_ty_unambig(bounded_ty));
10861087
walk_list!(visitor, visit_param_bound, bounds);
1088+
walk_list!(visitor, visit_where_predicate, bound_assumptions);
10871089
walk_list!(visitor, visit_generic_param, bound_generic_params);
10881090
}
10891091
WherePredicateKind::RegionPredicate(WhereRegionPredicate {
@@ -1292,6 +1294,7 @@ pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(
12921294
trait_ref: &'v PolyTraitRef<'v>,
12931295
) -> V::Result {
12941296
walk_list!(visitor, visit_generic_param, trait_ref.bound_generic_params);
1297+
walk_list!(visitor, visit_where_predicate, trait_ref.bound_assumptions);
12951298
visitor.visit_trait_ref(&trait_ref.trait_ref)
12961299
}
12971300

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

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

3838
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
3939
let mut bounds = Vec::new();
40-
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
40+
icx.lowerer().lower_bounds(
41+
item_ty,
42+
hir_bounds,
43+
&mut bounds,
44+
ty::List::empty(),
45+
ty::ListWithCachedTypeInfo::empty(),
46+
filter,
47+
);
4148
// Associated types are implicitly sized unless a `?Sized` bound is found
4249
match filter {
4350
PredicateFilter::All
@@ -326,7 +333,14 @@ fn opaque_type_bounds<'tcx>(
326333
ty::print::with_reduced_queries!({
327334
let icx = ItemCtxt::new(tcx, opaque_def_id);
328335
let mut bounds = Vec::new();
329-
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
336+
icx.lowerer().lower_bounds(
337+
item_ty,
338+
hir_bounds,
339+
&mut bounds,
340+
ty::List::empty(),
341+
ty::ListWithCachedTypeInfo::empty(),
342+
filter,
343+
);
330344
// Opaque types are implicitly sized unless a `?Sized` bound is found
331345
match filter {
332346
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
@@ -184,6 +184,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
184184
self_bounds,
185185
&mut bounds,
186186
ty::List::empty(),
187+
ty::ListWithCachedTypeInfo::empty(),
187188
PredicateFilter::All,
188189
);
189190
predicates.extend(bounds);
@@ -201,105 +202,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
201202
predicates.insert((trait_ref.upcast(tcx), tcx.def_span(def_id)));
202203
}
203204

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

304211
if tcx.features().generic_const_exprs() {
305212
predicates.extend(const_evaluatable_predicates_of(tcx, def_id, &predicates));
@@ -624,7 +531,14 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
624531

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

629543
let where_bounds_that_match =
630544
icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter);
@@ -924,12 +838,24 @@ impl<'tcx> ItemCtxt<'tcx> {
924838

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

841+
let mut bound_assumptions = FxIndexSet::default();
842+
if self.tcx.features().non_lifetime_binders() {
843+
self.lowerer().lower_where_predicates(
844+
predicate.bound_generic_params,
845+
predicate.bound_assumptions,
846+
&mut bound_assumptions,
847+
);
848+
}
849+
let bound_assumptions =
850+
self.tcx().mk_clauses_from_iter(bound_assumptions.into_iter().map(|(c, _)| c));
851+
927852
let bound_vars = self.tcx.late_bound_vars(hir_id);
928853
self.lowerer().lower_bounds(
929854
bound_ty,
930855
predicate.bounds,
931856
&mut bounds,
932857
bound_vars,
858+
bound_assumptions,
933859
filter,
934860
);
935861
}
@@ -1003,12 +929,25 @@ pub(super) fn const_conditions<'tcx>(
1003929
match pred.kind {
1004930
hir::WherePredicateKind::BoundPredicate(bound_pred) => {
1005931
let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
932+
933+
let mut bound_assumptions = FxIndexSet::default();
934+
if tcx.features().non_lifetime_binders() {
935+
icx.lowerer().lower_where_predicates(
936+
bound_pred.bound_generic_params,
937+
bound_pred.bound_assumptions,
938+
&mut bound_assumptions,
939+
);
940+
}
941+
let bound_assumptions =
942+
icx.tcx().mk_clauses_from_iter(bound_assumptions.into_iter().map(|(c, _)| c));
943+
1006944
let bound_vars = tcx.late_bound_vars(pred.hir_id);
1007945
icx.lowerer().lower_bounds(
1008946
ty,
1009947
bound_pred.bounds.iter(),
1010948
&mut bounds,
1011949
bound_vars,
950+
bound_assumptions,
1012951
PredicateFilter::ConstIfConst,
1013952
);
1014953
}
@@ -1029,6 +968,7 @@ pub(super) fn const_conditions<'tcx>(
1029968
supertraits,
1030969
&mut bounds,
1031970
ty::List::empty(),
971+
ty::ListWithCachedTypeInfo::empty(),
1032972
PredicateFilter::ConstIfConst,
1033973
);
1034974
}

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
}

0 commit comments

Comments
 (0)