Skip to content

Commit 788fb08

Browse files
committed
Reject relaxed bounds inside associated type bounds
1 parent 81af9d4 commit 788fb08

File tree

6 files changed

+37
-19
lines changed

6 files changed

+37
-19
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ enum RelaxedBoundPolicy<'a> {
296296
enum RelaxedBoundForbiddenReason {
297297
TraitObjectTy,
298298
SuperTrait,
299+
AssocTyBounds,
299300
LateBoundVarsInScope,
300301
}
301302

@@ -1102,9 +1103,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11021103
&*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
11031104
hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
11041105
} else {
1105-
// FIXME(#135229): These should be forbidden!
1106-
let bounds =
1107-
self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx);
1106+
let bounds = self.lower_param_bounds(
1107+
bounds,
1108+
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::AssocTyBounds),
1109+
itctx,
1110+
);
11081111
hir::AssocItemConstraintKind::Bound { bounds }
11091112
}
11101113
}
@@ -2117,7 +2120,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21172120
diag.emit();
21182121
return;
21192122
}
2120-
RelaxedBoundForbiddenReason::LateBoundVarsInScope => {}
2123+
RelaxedBoundForbiddenReason::AssocTyBounds
2124+
| RelaxedBoundForbiddenReason::LateBoundVarsInScope => {}
21212125
};
21222126
}
21232127
}

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
199199
// However, this can easily get out of sync! Ideally, we would perform this step
200200
// where we are guaranteed to catch *all* bounds like in
201201
// `Self::lower_poly_trait_ref`. List of concrete issues:
202-
// FIXME(more_maybe_bounds): We don't call this for e.g., trait object tys or
203-
// supertrait bounds!
202+
// FIXME(more_maybe_bounds): We don't call this for trait object tys, supertrait
203+
// bounds or associated type bounds (ATB)!
204204
// FIXME(trait_alias, #143122): We don't call it for the RHS. Arguably however,
205-
// AST lowering should reject them outright.
206-
// FIXME(associated_type_bounds): We don't call this for them. However, AST
207-
// lowering should reject them outright (#135229).
205+
// AST lowering should reject them outright.
208206
let bounds = collect_relaxed_bounds(hir_bounds, self_ty_where_predicates);
209207
self.check_and_report_invalid_relaxed_bounds(bounds);
210208
}

tests/ui/trait-bounds/more_maybe_bounds.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// FIXME(more_maybe_bounds): Even under `more_maybe_bounds` / `-Zexperimental-default-bounds`,
22
// trying to relax non-default bounds should still be an error in all contexts! As you can see
3-
// there are places like supertrait bounds and trait object types where we currently don't perform
4-
// this check.
3+
// there are places like supertrait bounds, trait object types or associated type bounds (ATB)
4+
// where we currently don't perform this check.
55
#![feature(auto_traits, more_maybe_bounds, negative_impls)]
66

77
trait Trait1 {}
@@ -13,11 +13,15 @@ trait Trait4 where Self: Trait1 {}
1313

1414
// FIXME: `?Trait2` should be rejected, `Trait2` isn't marked `#[lang = "default_traitN"]`.
1515
fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {}
16+
1617
fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
1718
//~^ ERROR bound modifier `?` can only be applied to default traits like `Sized`
1819
//~| ERROR bound modifier `?` can only be applied to default traits like `Sized`
1920
//~| ERROR bound modifier `?` can only be applied to default traits like `Sized`
2021

22+
// FIXME: `?Trait1` should be rejected, `Trait1` isn't marked `#[lang = "default_traitN"]`.
23+
fn baz<T>() where T: Iterator<Item: ?Trait1> {}
24+
2125
struct S;
2226
impl !Trait2 for S {}
2327
impl Trait1 for S {}

tests/ui/trait-bounds/more_maybe_bounds.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
error: bound modifier `?` can only be applied to default traits like `Sized`
2-
--> $DIR/more_maybe_bounds.rs:16:20
2+
--> $DIR/more_maybe_bounds.rs:17:20
33
|
44
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
55
| ^^^^^^^
66

77
error: bound modifier `?` can only be applied to default traits like `Sized`
8-
--> $DIR/more_maybe_bounds.rs:16:30
8+
--> $DIR/more_maybe_bounds.rs:17:30
99
|
1010
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
1111
| ^^^^^^^
1212

1313
error: bound modifier `?` can only be applied to default traits like `Sized`
14-
--> $DIR/more_maybe_bounds.rs:16:40
14+
--> $DIR/more_maybe_bounds.rs:17:40
1515
|
1616
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
1717
| ^^^^^^^

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ impl<T> S1<T> {
2222
fn f() where T: ?Sized {} //~ ERROR this relaxed bound is not permitted here
2323
}
2424

25+
// Test associated type bounds (ATB).
26+
// issue: <https://github.com/rust-lang/rust/issues/135229>
27+
struct S6<T>(T) where T: Iterator<Item: ?Sized>; //~ ERROR this relaxed bound is not permitted here
28+
2529
trait Tr: ?Sized {} //~ ERROR relaxed bounds are not permitted in supertrait bounds
2630

2731
// Test that relaxed `Sized` bounds are rejected in trait object types:

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,28 +38,36 @@ LL | fn f() where T: ?Sized {}
3838
|
3939
= note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item
4040

41+
error: this relaxed bound is not permitted here
42+
--> $DIR/relaxed-bounds-invalid-places.rs:27:41
43+
|
44+
LL | struct S6<T>(T) where T: Iterator<Item: ?Sized>;
45+
| ^^^^^^
46+
|
47+
= note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item
48+
4149
error: relaxed bounds are not permitted in supertrait bounds
42-
--> $DIR/relaxed-bounds-invalid-places.rs:25:11
50+
--> $DIR/relaxed-bounds-invalid-places.rs:29:11
4351
|
4452
LL | trait Tr: ?Sized {}
4553
| ^^^^^^
4654
|
4755
= note: traits are `?Sized` by default
4856

4957
error: relaxed bounds are not permitted in trait object types
50-
--> $DIR/relaxed-bounds-invalid-places.rs:29:20
58+
--> $DIR/relaxed-bounds-invalid-places.rs:33:20
5159
|
5260
LL | type O1 = dyn Tr + ?Sized;
5361
| ^^^^^^
5462

5563
error: relaxed bounds are not permitted in trait object types
56-
--> $DIR/relaxed-bounds-invalid-places.rs:30:15
64+
--> $DIR/relaxed-bounds-invalid-places.rs:34:15
5765
|
5866
LL | type O2 = dyn ?Sized + ?Sized + Tr;
5967
| ^^^^^^
6068

6169
error: relaxed bounds are not permitted in trait object types
62-
--> $DIR/relaxed-bounds-invalid-places.rs:30:24
70+
--> $DIR/relaxed-bounds-invalid-places.rs:34:24
6371
|
6472
LL | type O2 = dyn ?Sized + ?Sized + Tr;
6573
| ^^^^^^
@@ -76,5 +84,5 @@ error: bound modifier `?` can only be applied to `Sized`
7684
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
7785
| ^^^^^^^^^^^^^^^
7886

79-
error: aborting due to 11 previous errors
87+
error: aborting due to 12 previous errors
8088

0 commit comments

Comments
 (0)