Skip to content

Commit 729ee29

Browse files
Support trait predicates on poly trait refs
1 parent 1dc00a3 commit 729ee29

File tree

9 files changed

+70
-16
lines changed

9 files changed

+70
-16
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -2115,10 +2115,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21152115
itctx: &ImplTraitContext,
21162116
constness: ast::Const,
21172117
) -> hir::PolyTraitRef<'hir> {
2118+
let binder_predicates =
2119+
self.arena.alloc_from_iter(p.bound_generic_params.iter().filter_map(|param| {
2120+
self.lower_generic_bound_predicate(
2121+
param.ident,
2122+
param.id,
2123+
&param.kind,
2124+
&param.bounds,
2125+
param.colon_span,
2126+
p.span,
2127+
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
2128+
hir::PredicateOrigin::GenericParam,
2129+
)
2130+
}));
21182131
let bound_generic_params =
21192132
self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
21202133
let trait_ref = self.lower_trait_ref(constness, &p.trait_ref, itctx);
2121-
hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
2134+
hir::PolyTraitRef {
2135+
bound_generic_params,
2136+
binder_predicates,
2137+
trait_ref,
2138+
span: self.lower_span(p.span),
2139+
}
21222140
}
21232141

21242142
fn lower_mt(&mut self, mt: &MutTy, itctx: &ImplTraitContext) -> hir::MutTy<'hir> {
@@ -2425,6 +2443,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24252443
Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
24262444
let principal = hir::PolyTraitRef {
24272445
bound_generic_params: &[],
2446+
binder_predicates: &[],
24282447
trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
24292448
span: self.lower_span(span),
24302449
};

compiler/rustc_hir/src/hir.rs

+3
Original file line numberDiff line numberDiff line change
@@ -3002,6 +3002,9 @@ pub struct PolyTraitRef<'hir> {
30023002
/// The `'a` in `for<'a> Foo<&'a T>`.
30033003
pub bound_generic_params: &'hir [GenericParam<'hir>],
30043004

3005+
/// Predicates on the `for<T>` binder itself, such as `for<T: Trait> ...`
3006+
pub binder_predicates: &'hir [WherePredicate<'hir>],
3007+
30053008
/// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`.
30063009
pub trait_ref: TraitRef<'hir>,
30073010

compiler/rustc_hir/src/intravisit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,7 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB
10881088
pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_ref: &'v PolyTraitRef<'v>) {
10891089
walk_list!(visitor, visit_generic_param, trait_ref.bound_generic_params);
10901090
visitor.visit_trait_ref(&trait_ref.trait_ref);
1091+
walk_list!(visitor, visit_where_predicate, trait_ref.binder_predicates);
10911092
}
10921093

10931094
pub fn walk_struct_def<'v, V: Visitor<'v>>(

compiler/rustc_hir_analysis/src/astconv/bounds.rs

+16-8
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use crate::errors;
1818
impl<'tcx> dyn AstConv<'tcx> + '_ {
1919
pub(crate) fn lower_where_predicates(
2020
&self,
21-
params: &'tcx [hir::GenericParam<'tcx>],
22-
hir_predicates: &'tcx [hir::WherePredicate<'tcx>],
21+
params: &[hir::GenericParam<'_>],
22+
hir_predicates: &[hir::WherePredicate<'_>],
2323
predicates: &mut FxIndexSet<(ty::Clause<'tcx>, Span)>,
2424
) {
2525
// Collect the predicates that were written inline by the user on each
@@ -140,19 +140,19 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
140140
}
141141

142142
/// Sets `implicitly_sized` to true on `Bounds` if necessary
143-
pub(crate) fn add_implicitly_sized(
143+
pub(crate) fn add_implicitly_sized<'hir>(
144144
&self,
145145
bounds: &mut Bounds<'tcx>,
146146
self_ty: Ty<'tcx>,
147-
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
148-
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
147+
ast_bounds: &'hir [hir::GenericBound<'hir>],
148+
self_ty_where_predicates: Option<(LocalDefId, &'hir [hir::WherePredicate<'hir>])>,
149149
span: Span,
150150
) {
151151
let tcx = self.tcx();
152152

153153
// Try to find an unbound in bounds.
154154
let mut unbound = None;
155-
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
155+
let mut search_bounds = |ast_bounds: &'hir [hir::GenericBound<'hir>]| {
156156
for ab in ast_bounds {
157157
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
158158
if unbound.is_none() {
@@ -244,8 +244,16 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
244244
hir::TraitBoundModifier::Maybe => continue,
245245
};
246246

247-
// TODO: Add in the binder preds from the poly trait ref.
248-
let binder_predicates = binder_predicates;
247+
let mut additional_binder_predicates = FxIndexSet::default();
248+
self.lower_where_predicates(
249+
poly_trait_ref.bound_generic_params,
250+
poly_trait_ref.binder_predicates,
251+
&mut additional_binder_predicates,
252+
);
253+
let binder_predicates =
254+
self.tcx().mk_clauses_from_iter(binder_predicates.into_iter().chain(
255+
additional_binder_predicates.into_iter().map(|(clause, _)| clause),
256+
));
249257

250258
let _ = self.instantiate_poly_trait_ref(
251259
&poly_trait_ref.trait_ref,

compiler/rustc_hir_analysis/src/astconv/object_safety.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
3434
let mut potential_assoc_types = Vec::new();
3535
let dummy_self = self.tcx().types.trait_object_dummy_self;
3636
for trait_bound in hir_trait_bounds.iter().rev() {
37+
assert!(
38+
trait_bound.binder_predicates.is_empty(),
39+
"FIXME(non_lifetime_binders): object types should not have binders"
40+
);
3741
if let GenericArgCountResult {
3842
correct:
3943
Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }),
@@ -46,7 +50,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
4650
dummy_self,
4751
&mut bounds,
4852
false,
49-
// TODO: dyn traits should have no binder preds
5053
ty::List::empty(),
5154
// FIXME: This should be `true`, but we don't really handle
5255
// associated type bounds or type aliases in objects in a way

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,16 @@ impl<'tcx> ItemCtxt<'tcx> {
712712
}
713713
};
714714

715+
let mut binder_predicates = FxIndexSet::default();
716+
self.astconv().lower_where_predicates(
717+
predicate.bound_generic_params,
718+
predicate.binder_predicates,
719+
&mut binder_predicates,
720+
);
721+
let binder_predicates = self
722+
.tcx
723+
.mk_clauses_from_iter(binder_predicates.into_iter().map(|(clause, _)| clause));
724+
715725
// Subtle: If we're collecting `SelfAndAssociatedTypeBounds`, then we
716726
// want to only consider predicates with `Self: ...`, but we don't want
717727
// `OnlySelfBounds(true)` since we want to collect the nested associated
@@ -733,8 +743,7 @@ impl<'tcx> ItemCtxt<'tcx> {
733743
}),
734744
&mut bounds,
735745
bound_vars,
736-
// TODO: convert `where_bound_predicate` above accordingly
737-
ty::List::empty(),
746+
binder_predicates,
738747
only_self_bounds,
739748
);
740749
}

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+1
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
398398
self.with(scope, |this| {
399399
walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
400400
this.visit_trait_ref(&trait_ref.trait_ref);
401+
walk_list!(this, visit_where_predicate, trait_ref.binder_predicates);
401402
});
402403
}
403404
}

compiler/rustc_hir_analysis/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ pub fn hir_trait_to_predicates<'tcx>(
266266
self_ty,
267267
&mut bounds,
268268
true,
269-
// TODO: This is probably wrong!
269+
// FIXME(non_lifetime_binders): This is probably not right.
270270
ty::List::empty(),
271271
OnlySelfBounds(false),
272272
);

compiler/rustc_middle/src/ty/mod.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -821,18 +821,28 @@ impl<'tcx> Clause<'tcx> {
821821
let pred_bound_vars = bound_pred.bound_vars();
822822
let trait_bound_vars = trait_ref.bound_vars();
823823
// 1) Self: Bar1<'a, '^0.0> -> Self: Bar1<'a, '^0.1>
824-
let shifted_pred =
825-
tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder());
824+
let (shifted_pred, shifted_bound_clauses) = tcx.shift_bound_var_indices(
825+
trait_bound_vars.len(),
826+
(bound_pred.skip_binder(), bound_pred.skip_binder_predicates()),
827+
);
826828
// 2) Self: Bar1<'a, '^0.1> -> T: Bar1<'^0.0, '^0.1>
827829
let new = EarlyBinder::bind(shifted_pred).instantiate(tcx, trait_ref.skip_binder().args);
828830
// 3) ['x] + ['b] -> ['x, 'b]
829831
let bound_vars =
830832
tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars));
831833

834+
let binder_predicates = tcx.mk_clauses_from_iter(
835+
trait_ref.skip_binder_predicates().into_iter().chain(shifted_bound_clauses),
836+
);
837+
832838
// FIXME: Is it really perf sensitive to use reuse_or_mk_predicate here?
833839
tcx.reuse_or_mk_predicate(
834840
self.as_predicate(),
835-
ty::Binder::bind_with_vars(PredicateKind::Clause(new), bound_vars),
841+
ty::Binder::bind_with_vars_and_predicates(
842+
PredicateKind::Clause(new),
843+
bound_vars,
844+
binder_predicates,
845+
),
836846
)
837847
.expect_clause()
838848
}

0 commit comments

Comments
 (0)