Skip to content

Commit ce68cd3

Browse files
committed
Reject relaxed bounds inside trait alias bounds
1 parent 690a8a6 commit ce68cd3

18 files changed

+131
-116
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
426426
|this| {
427427
this.lower_param_bounds(
428428
bounds,
429-
RelaxedBoundPolicy::Allowed,
429+
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitAlias),
430430
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
431431
)
432432
},

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ enum RelaxedBoundPolicy<'a> {
296296
enum RelaxedBoundForbiddenReason {
297297
TraitObjectTy,
298298
SuperTrait,
299+
TraitAlias,
299300
AssocTyBounds,
300301
LateBoundVarsInScope,
301302
}
@@ -2132,6 +2133,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21322133
gate("supertrait bounds", "traits");
21332134
return;
21342135
}
2136+
RelaxedBoundForbiddenReason::TraitAlias => {
2137+
gate("trait alias bounds", "trait aliases");
2138+
return;
2139+
}
21352140
RelaxedBoundForbiddenReason::AssocTyBounds
21362141
| RelaxedBoundForbiddenReason::LateBoundVarsInScope => {}
21372142
};

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
202202
// where we are guaranteed to catch *all* bounds like in
203203
// `Self::lower_poly_trait_ref`. List of concrete issues:
204204
// FIXME(more_maybe_bounds): We don't call this for trait object tys, supertrait
205-
// bounds or associated type bounds (ATB)!
206-
// FIXME(trait_alias, #143122): We don't call it for the RHS. Arguably however,
207-
// AST lowering should reject them outright.
205+
// bounds, trait alias bounds, assoc type bounds (ATB)!
208206
let bounds = collect_relaxed_bounds(hir_bounds, self_ty_where_predicates);
209207
self.check_and_report_invalid_relaxed_bounds(bounds);
210208
}

tests/rustdoc-ui/doc-alias-assoc-const.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(trait_alias)]
2-
31
pub struct Foo;
42

53
pub trait Bar {

tests/rustdoc-ui/doc-alias-assoc-const.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: `#[doc(alias = "...")]` isn't allowed on associated constant in trait implementation block
2-
--> $DIR/doc-alias-assoc-const.rs:10:11
2+
--> $DIR/doc-alias-assoc-const.rs:8:11
33
|
44
LL | #[doc(alias = "CONST_BAZ")]
55
| ^^^^^^^^^^^^^^^^^^^

tests/ui/sized-hierarchy/trait-aliases.rs

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Test that we reject trait object types that effectively (i.e., after trait alias expansion)
2+
// don't contain any bounds.
3+
4+
#![feature(trait_alias)]
5+
6+
trait Empty0 =;
7+
8+
// Nest a couple of levels deep:
9+
trait Empty1 = Empty0;
10+
trait Empty2 = Empty1;
11+
12+
// Straight list expansion:
13+
type Type0 = dyn Empty2; //~ ERROR at least one trait is required for an object type [E0224]
14+
15+
// Twice:
16+
trait Empty3 = Empty2 + Empty2;
17+
18+
type Type1 = dyn Empty3; //~ ERROR at least one trait is required for an object type [E0224]
19+
20+
fn main() {}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0224]: at least one trait is required for an object type
2+
--> $DIR/effectively-empty-trait-object-type.rs:13:14
3+
|
4+
LL | trait Empty2 = Empty1;
5+
| ------------ this alias does not contain a trait
6+
...
7+
LL | type Type0 = dyn Empty2;
8+
| ^^^^^^^^^^
9+
10+
error[E0224]: at least one trait is required for an object type
11+
--> $DIR/effectively-empty-trait-object-type.rs:18:14
12+
|
13+
LL | trait Empty3 = Empty2 + Empty2;
14+
| ------------ this alias does not contain a trait
15+
LL |
16+
LL | type Type1 = dyn Empty3;
17+
| ^^^^^^^^^^
18+
19+
error: aborting due to 2 previous errors
20+
21+
For more information about this error, try `rustc --explain E0224`.

tests/ui/traits/alias/empty.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Ensure that there are straightforward ways to define "empty" / "trivial" / "unit" trait aliases
2+
// which don't impose any constraints when used as a bound (since they expand to nothing).
3+
//@ check-pass
4+
#![feature(trait_alias)]
5+
6+
trait Empty =;
7+
8+
trait Trivial = where;
9+
10+
trait Unit = where Self:;
11+
12+
fn check<T: ?Sized + Empty>() {}
13+
14+
fn main() {
15+
check::<()>(); // OK. "`(): Empty`" is trivially satisfied
16+
check::<str>(); // OK. `Empty` is truly empty and isn't implicitly bounded by `Sized`.
17+
}

tests/ui/traits/alias/maybe-bound.rs

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)