Skip to content

Commit e985804

Browse files
committed
Auto merge of rust-lang#115362 - compiler-errors:non-lifetime-binder-where-clauses, r=<try>
[WIP] Support param bounds on non-lifetime binders This PR adds resolution and AST lowering for where clauses on binders. The meaning for `for<T>` now becomes `for<T: Sized>` like regular generics positions, and you are now able to write `for<T: Trait>` (and `for<T: ?Sized>`). Binder predicates are only considered in the new solver today. Since non-lifetime binders is an incomplete feature, I don't think we need to do any messaging to tell people that they don't work correctly in the old solver, but I'll see to that in a follow-up. This PR then adds a new `List<ty::Clause>` to binders. Most places in the compiler shouldn't care about them existing, but eventually as support for non-lifetime binders gets fleshed out we should be more careful about asserting that they're handled. This will not happen in this PR. Tracking: * rust-lang#108185
2 parents d4812c8 + f3652c5 commit e985804

File tree

62 files changed

+798
-343
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+798
-343
lines changed

compiler/rustc_ast_lowering/src/item.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
18181818
bounded_ty: self.arena.alloc(bounded_ty),
18191819
bounds,
18201820
bound_generic_params: &[],
1821+
bound_assumptions: &[],
18211822
origin,
18221823
})
18231824
}
@@ -1846,6 +1847,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
18461847
}) => hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
18471848
bound_generic_params: self
18481849
.lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder),
1850+
bound_assumptions: self.arena.alloc_from_iter(
1851+
bound_generic_params.iter().filter_map(|param| {
1852+
self.lower_generic_bound_predicate(
1853+
param.ident,
1854+
param.id,
1855+
&param.kind,
1856+
&param.bounds,
1857+
param.colon_span,
1858+
span,
1859+
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1860+
PredicateOrigin::GenericParam,
1861+
)
1862+
}),
1863+
),
18491864
bounded_ty: self
18501865
.lower_ty(bounded_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
18511866
bounds: self.lower_param_bounds(

compiler/rustc_ast_lowering/src/lib.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ 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::{
5858
self as hir, ConstArg, GenericArg, HirId, IsAnonInPath, ItemLocalMap, LangItem, ParamName,
59-
TraitCandidate,
59+
PredicateOrigin, TraitCandidate,
6060
};
6161
use rustc_index::{Idx, IndexSlice, IndexVec};
6262
use rustc_macros::extension;
@@ -1728,6 +1728,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17281728

17291729
hir::GenericBound::Trait(hir::PolyTraitRef {
17301730
bound_generic_params: &[],
1731+
bound_assumptions: &[],
17311732
modifiers: hir::TraitBoundModifiers::NONE,
17321733
trait_ref: hir::TraitRef {
17331734
path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
@@ -1948,12 +1949,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
19481949
p: &PolyTraitRef,
19491950
itctx: ImplTraitContext,
19501951
) -> 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+
}));
19511965
let bound_generic_params =
19521966
self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
19531967
let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
19541968
let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
19551969
hir::PolyTraitRef {
19561970
bound_generic_params,
1971+
bound_assumptions,
19571972
modifiers,
19581973
trait_ref,
19591974
span: self.lower_span(p.span),
@@ -2362,6 +2377,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23622377
Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
23632378
let principal = hir::PolyTraitRef {
23642379
bound_generic_params: &[],
2380+
bound_assumptions: &[],
23652381
modifiers: hir::TraitBoundModifiers::NONE,
23662382
trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
23672383
span: self.lower_span(span),

compiler/rustc_ast_passes/src/feature_gate.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,12 @@ impl<'a> PostExpansionVisitor<'a> {
140140
}
141141
}
142142

143-
for param in params {
144-
if !param.bounds.is_empty() {
145-
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
146-
self.sess.dcx().emit_err(errors::ForbiddenBound { spans });
143+
if !self.features.non_lifetime_binders() {
144+
for param in params {
145+
if !param.bounds.is_empty() {
146+
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
147+
self.sess.dcx().emit_err(errors::ForbiddenBound { spans });
148+
}
147149
}
148150
}
149151
}

compiler/rustc_borrowck/src/type_check/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1641,7 +1641,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
16411641
let expected_ty = self.infcx.instantiate_binder_with_fresh_vars(
16421642
self.body().source_info(location).span,
16431643
BoundRegionConversionTime::HigherRankedType,
1644-
binder_ty.into(),
1644+
*binder_ty,
16451645
);
16461646
self.sub_types(
16471647
operand_ty,
@@ -1891,7 +1891,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
18911891
let found_ty = self.infcx.instantiate_binder_with_fresh_vars(
18921892
self.body.source_info(location).span,
18931893
BoundRegionConversionTime::HigherRankedType,
1894-
binder_ty.into(),
1894+
*binder_ty,
18951895
);
18961896
self.relate_types(
18971897
ty,

compiler/rustc_hir/src/hir.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,8 @@ pub struct WhereBoundPredicate<'hir> {
990990
pub origin: PredicateOrigin,
991991
/// Any generics from a `for` binding.
992992
pub bound_generic_params: &'hir [GenericParam<'hir>],
993+
/// The `'a + Trait` in `for<T: 'a + Trait> ...`
994+
pub bound_assumptions: &'hir [WherePredicate<'hir>],
993995
/// The type being bounded.
994996
pub bounded_ty: &'hir Ty<'hir>,
995997
/// Trait and lifetime bounds (e.g., `Clone + Send + 'static`).
@@ -3840,6 +3842,9 @@ pub struct PolyTraitRef<'hir> {
38403842
/// The `'a` in `for<'a> Foo<&'a T>`.
38413843
pub bound_generic_params: &'hir [GenericParam<'hir>],
38423844

3845+
/// The `'a + Trait` in `for<T: 'a + Trait> ...`
3846+
pub bound_assumptions: &'hir [WherePredicate<'hir>],
3847+
38433848
/// The constness and polarity of the trait ref.
38443849
///
38453850
/// The `async` modifier is lowered directly into a different trait for now.
@@ -4843,7 +4848,7 @@ mod size_asserts {
48434848
static_assert_size!(ForeignItem<'_>, 88);
48444849
static_assert_size!(ForeignItemKind<'_>, 56);
48454850
static_assert_size!(GenericArg<'_>, 16);
4846-
static_assert_size!(GenericBound<'_>, 64);
4851+
static_assert_size!(GenericBound<'_>, 80);
48474852
static_assert_size!(Generics<'_>, 56);
48484853
static_assert_size!(Impl<'_>, 80);
48494854
static_assert_size!(ImplItem<'_>, 88);

compiler/rustc_hir/src/intravisit.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1082,10 +1082,12 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
10821082
ref bounded_ty,
10831083
bounds,
10841084
bound_generic_params,
1085+
bound_assumptions,
10851086
origin: _,
10861087
}) => {
10871088
try_visit!(visitor.visit_ty_unambig(bounded_ty));
10881089
walk_list!(visitor, visit_param_bound, bounds);
1090+
walk_list!(visitor, visit_where_predicate, bound_assumptions);
10891091
walk_list!(visitor, visit_generic_param, bound_generic_params);
10901092
}
10911093
WherePredicateKind::RegionPredicate(WhereRegionPredicate {
@@ -1296,6 +1298,7 @@ pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(
12961298
trait_ref: &'v PolyTraitRef<'v>,
12971299
) -> V::Result {
12981300
walk_list!(visitor, visit_generic_param, trait_ref.bound_generic_params);
1301+
walk_list!(visitor, visit_where_predicate, trait_ref.bound_assumptions);
12991302
visitor.visit_trait_ref(&trait_ref.trait_ref)
13001303
}
13011304

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

0 commit comments

Comments
 (0)