Skip to content

Commit 1b39cd5

Browse files
committed
Eagerly decide whether relaxed bounds are allowed or not
1 parent 4530eac commit 1b39cd5

4 files changed

Lines changed: 35 additions & 45 deletions

File tree

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,7 +1986,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
19861986
bounds: &[GenericBound],
19871987
colon_span: Option<Span>,
19881988
parent_span: Span,
1989-
rbp: RelaxedBoundPolicy<'_>,
1989+
rbp: RelaxedBoundPolicy,
19901990
itctx: ImplTraitContext,
19911991
origin: PredicateOrigin,
19921992
) -> Option<hir::WherePredicate<'hir>> {
@@ -2061,8 +2061,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
20612061
bounded_ty,
20622062
bounds,
20632063
}) => {
2064-
let rbp = if bound_generic_params.is_empty() {
2065-
RelaxedBoundPolicy::AllowedIfOnTyParam(bounded_ty.id, params)
2064+
let bounded_ty = self.lower_ty_alloc(
2065+
bounded_ty,
2066+
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
2067+
);
2068+
let rbp = if bound_generic_params.is_empty()
2069+
&& let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = bounded_ty.kind
2070+
&& let Res::Def(DefKind::TyParam, def_id) = path.res
2071+
&& params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id())
2072+
{
2073+
RelaxedBoundPolicy::Allowed
20662074
} else {
20672075
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::LateBoundVarsInScope)
20682076
};
@@ -2071,10 +2079,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
20712079
bound_generic_params,
20722080
hir::GenericParamSource::Binder,
20732081
),
2074-
bounded_ty: self.lower_ty_alloc(
2075-
bounded_ty,
2076-
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
2077-
),
2082+
bounded_ty,
20782083
bounds: self.lower_param_bounds(
20792084
bounds,
20802085
rbp,

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,8 @@ impl<'tcx> ResolverAstLowering<'tcx> {
318318
/// Relaxed bounds should only be allowed in places where we later
319319
/// (namely during HIR ty lowering) perform *sized elaboration*.
320320
#[derive(Clone, Copy, Debug)]
321-
enum RelaxedBoundPolicy<'a> {
321+
enum RelaxedBoundPolicy {
322322
Allowed,
323-
AllowedIfOnTyParam(NodeId, &'a [ast::GenericParam]),
324323
Forbidden(RelaxedBoundForbiddenReason),
325324
}
326325

@@ -1955,7 +1954,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
19551954
fn lower_param_bound(
19561955
&mut self,
19571956
tpb: &GenericBound,
1958-
rbp: RelaxedBoundPolicy<'_>,
1957+
rbp: RelaxedBoundPolicy,
19591958
itctx: ImplTraitContext,
19601959
) -> hir::GenericBound<'hir> {
19611960
match tpb {
@@ -2193,7 +2192,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
21932192
fn lower_poly_trait_ref(
21942193
&mut self,
21952194
PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef,
2196-
rbp: RelaxedBoundPolicy<'_>,
2195+
rbp: RelaxedBoundPolicy,
21972196
itctx: ImplTraitContext,
21982197
) -> hir::PolyTraitRef<'hir> {
21992198
let bound_generic_params =
@@ -2217,7 +2216,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
22172216
&self,
22182217
trait_ref: hir::TraitRef<'_>,
22192218
span: Span,
2220-
rbp: RelaxedBoundPolicy<'_>,
2219+
rbp: RelaxedBoundPolicy,
22212220
) {
22222221
// Even though feature `more_maybe_bounds` enables the user to relax all default bounds
22232222
// other than `Sized` in a lot more positions (thereby bypassing the given policy), we don't
@@ -2230,14 +2229,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
22302229

22312230
match rbp {
22322231
RelaxedBoundPolicy::Allowed => return,
2233-
RelaxedBoundPolicy::AllowedIfOnTyParam(id, params) => {
2234-
if let Some(res) = self.get_partial_res(id).and_then(|r| r.full_res())
2235-
&& let Res::Def(DefKind::TyParam, def_id) = res
2236-
&& params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id())
2237-
{
2238-
return;
2239-
}
2240-
}
22412232
RelaxedBoundPolicy::Forbidden(reason) => {
22422233
let gate = |context, subject| {
22432234
let extended = self.tcx.features().more_maybe_bounds();
@@ -2299,7 +2290,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
22992290
fn lower_param_bounds(
23002291
&mut self,
23012292
bounds: &[GenericBound],
2302-
rbp: RelaxedBoundPolicy<'_>,
2293+
rbp: RelaxedBoundPolicy,
23032294
itctx: ImplTraitContext,
23042295
) -> hir::GenericBounds<'hir> {
23052296
self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, rbp, itctx))
@@ -2308,7 +2299,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
23082299
fn lower_param_bounds_mut(
23092300
&mut self,
23102301
bounds: &[GenericBound],
2311-
rbp: RelaxedBoundPolicy<'_>,
2302+
rbp: RelaxedBoundPolicy,
23122303
itctx: ImplTraitContext,
23132304
) -> impl Iterator<Item = hir::GenericBound<'hir>> {
23142305
bounds.iter().map(move |bound| self.lower_param_bound(bound, rbp, itctx))

tests/ui/unsized/relaxed-bounds-invalid-places.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
// Relaxed bounds are only permitted inside impl-Trait, assoc ty item bounds and
44
// on type params defined by the closest item.
55

6-
struct S1<T>(T) where (T): ?Sized; //~ ERROR this relaxed bound is not permitted here
6+
// This used to not be allowed, because we looked at the AST.
7+
// Now we're handling this at the HIR level, we don't care about parentheses anymore.
8+
struct S1<T>(T) where (T): ?Sized;
79

810
struct S2<T>(T) where u8: ?Sized; //~ ERROR this relaxed bound is not permitted here
911

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,101 @@
11
error: this relaxed bound is not permitted here
2-
--> $DIR/relaxed-bounds-invalid-places.rs:6:28
3-
|
4-
LL | struct S1<T>(T) where (T): ?Sized;
5-
| ^^^^^^
6-
|
7-
= note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item
8-
9-
error: this relaxed bound is not permitted here
10-
--> $DIR/relaxed-bounds-invalid-places.rs:8:27
2+
--> $DIR/relaxed-bounds-invalid-places.rs:10:27
113
|
124
LL | struct S2<T>(T) where u8: ?Sized;
135
| ^^^^^^
146
|
157
= note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item
168

179
error: this relaxed bound is not permitted here
18-
--> $DIR/relaxed-bounds-invalid-places.rs:10:35
10+
--> $DIR/relaxed-bounds-invalid-places.rs:12:35
1911
|
2012
LL | struct S3<T>(T) where &'static T: ?Sized;
2113
| ^^^^^^
2214
|
2315
= note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item
2416

2517
error: this relaxed bound is not permitted here
26-
--> $DIR/relaxed-bounds-invalid-places.rs:14:34
18+
--> $DIR/relaxed-bounds-invalid-places.rs:16:34
2719
|
2820
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
2921
| ^^^^^^^^^^
3022
|
3123
= note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item
3224

3325
error: this relaxed bound is not permitted here
34-
--> $DIR/relaxed-bounds-invalid-places.rs:22:21
26+
--> $DIR/relaxed-bounds-invalid-places.rs:24:21
3527
|
3628
LL | fn f() where T: ?Sized {}
3729
| ^^^^^^
3830
|
3931
= note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item
4032

4133
error: this relaxed bound is not permitted here
42-
--> $DIR/relaxed-bounds-invalid-places.rs:27:41
34+
--> $DIR/relaxed-bounds-invalid-places.rs:29:41
4335
|
4436
LL | struct S6<T>(T) where T: Iterator<Item: ?Sized>;
4537
| ^^^^^^
4638
|
4739
= note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item
4840

4941
error: relaxed bounds are not permitted in supertrait bounds
50-
--> $DIR/relaxed-bounds-invalid-places.rs:29:11
42+
--> $DIR/relaxed-bounds-invalid-places.rs:31:11
5143
|
5244
LL | trait Tr: ?Sized {}
5345
| ^^^^^^
5446
|
5547
= note: traits are not implicitly bounded by `Sized`, so there is nothing to relax
5648

5749
error: relaxed bounds are not permitted in trait object types
58-
--> $DIR/relaxed-bounds-invalid-places.rs:33:15
50+
--> $DIR/relaxed-bounds-invalid-places.rs:35:15
5951
|
6052
LL | type O0 = dyn ?Sized;
6153
| ^^^^^^
6254
|
6355
= note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax
6456

6557
error: relaxed bounds are not permitted in trait object types
66-
--> $DIR/relaxed-bounds-invalid-places.rs:36:20
58+
--> $DIR/relaxed-bounds-invalid-places.rs:38:20
6759
|
6860
LL | type O1 = dyn Tr + ?Sized;
6961
| ^^^^^^
7062
|
7163
= note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax
7264

7365
error: relaxed bounds are not permitted in trait object types
74-
--> $DIR/relaxed-bounds-invalid-places.rs:37:15
66+
--> $DIR/relaxed-bounds-invalid-places.rs:39:15
7567
|
7668
LL | type O2 = dyn ?Sized + ?Sized + Tr;
7769
| ^^^^^^
7870
|
7971
= note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax
8072

8173
error: relaxed bounds are not permitted in trait object types
82-
--> $DIR/relaxed-bounds-invalid-places.rs:37:24
74+
--> $DIR/relaxed-bounds-invalid-places.rs:39:24
8375
|
8476
LL | type O2 = dyn ?Sized + ?Sized + Tr;
8577
| ^^^^^^
8678
|
8779
= note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax
8880

8981
error: bound modifier `?` can only be applied to `Sized`
90-
--> $DIR/relaxed-bounds-invalid-places.rs:14:34
82+
--> $DIR/relaxed-bounds-invalid-places.rs:16:34
9183
|
9284
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
9385
| ^^^^^^^^^^
9486

9587
error: bound modifier `?` can only be applied to `Sized`
96-
--> $DIR/relaxed-bounds-invalid-places.rs:18:33
88+
--> $DIR/relaxed-bounds-invalid-places.rs:20:33
9789
|
9890
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
9991
| ^^^^^^^^^^^^^^^
10092

10193
error[E0224]: at least one trait is required for an object type
102-
--> $DIR/relaxed-bounds-invalid-places.rs:33:11
94+
--> $DIR/relaxed-bounds-invalid-places.rs:35:11
10395
|
10496
LL | type O0 = dyn ?Sized;
10597
| ^^^^^^^^^^
10698

107-
error: aborting due to 14 previous errors
99+
error: aborting due to 13 previous errors
108100

109101
For more information about this error, try `rustc --explain E0224`.

0 commit comments

Comments
 (0)