Skip to content

Reject relaxed bounds inside associated type bounds (ATB) #135331

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ enum RelaxedBoundPolicy<'a> {
enum RelaxedBoundForbiddenReason {
TraitObjectTy,
SuperTrait,
AssocTyBounds,
LateBoundVarsInScope,
}

Expand Down Expand Up @@ -1102,9 +1103,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
} else {
// FIXME(#135229): These should be forbidden!
let bounds =
self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx);
let bounds = self.lower_param_bounds(
bounds,
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::AssocTyBounds),
itctx,
);
hir::AssocItemConstraintKind::Bound { bounds }
}
}
Expand Down Expand Up @@ -2117,7 +2120,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
diag.emit();
return;
}
RelaxedBoundForbiddenReason::LateBoundVarsInScope => {}
RelaxedBoundForbiddenReason::AssocTyBounds
| RelaxedBoundForbiddenReason::LateBoundVarsInScope => {}
};
}
}
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// However, this can easily get out of sync! Ideally, we would perform this step
// where we are guaranteed to catch *all* bounds like in
// `Self::lower_poly_trait_ref`. List of concrete issues:
// FIXME(more_maybe_bounds): We don't call this for e.g., trait object tys or
// supertrait bounds!
// FIXME(more_maybe_bounds): We don't call this for trait object tys, supertrait
// bounds or associated type bounds (ATB)!
// FIXME(trait_alias, #143122): We don't call it for the RHS. Arguably however,
// AST lowering should reject them outright.
// FIXME(associated_type_bounds): We don't call this for them. However, AST
// lowering should reject them outright (#135229).
// AST lowering should reject them outright.
let bounds = collect_relaxed_bounds(hir_bounds, self_ty_where_predicates);
self.check_and_report_invalid_relaxed_bounds(bounds);
}
Expand Down
8 changes: 6 additions & 2 deletions tests/ui/trait-bounds/more_maybe_bounds.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// FIXME(more_maybe_bounds): Even under `more_maybe_bounds` / `-Zexperimental-default-bounds`,
// trying to relax non-default bounds should still be an error in all contexts! As you can see
// there are places like supertrait bounds and trait object types where we currently don't perform
// this check.
// there are places like supertrait bounds, trait object types or associated type bounds (ATB)
// where we currently don't perform this check.
#![feature(auto_traits, more_maybe_bounds, negative_impls)]

trait Trait1 {}
Expand All @@ -13,11 +13,15 @@ trait Trait4 where Self: Trait1 {}

// FIXME: `?Trait2` should be rejected, `Trait2` isn't marked `#[lang = "default_traitN"]`.
fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {}

fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
//~^ ERROR bound modifier `?` can only be applied to default traits like `Sized`
//~| ERROR bound modifier `?` can only be applied to default traits like `Sized`
//~| ERROR bound modifier `?` can only be applied to default traits like `Sized`

// FIXME: `?Trait1` should be rejected, `Trait1` isn't marked `#[lang = "default_traitN"]`.
fn baz<T>() where T: Iterator<Item: ?Trait1> {}

struct S;
impl !Trait2 for S {}
impl Trait1 for S {}
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/trait-bounds/more_maybe_bounds.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
error: bound modifier `?` can only be applied to default traits like `Sized`
--> $DIR/more_maybe_bounds.rs:16:20
--> $DIR/more_maybe_bounds.rs:17:20
|
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
| ^^^^^^^

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

error: bound modifier `?` can only be applied to default traits like `Sized`
--> $DIR/more_maybe_bounds.rs:16:40
--> $DIR/more_maybe_bounds.rs:17:40
|
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
| ^^^^^^^
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/unsized/relaxed-bounds-invalid-places.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ impl<T> S1<T> {
fn f() where T: ?Sized {} //~ ERROR this relaxed bound is not permitted here
}

// Test associated type bounds (ATB).
// issue: <https://github.com/rust-lang/rust/issues/135229>
struct S6<T>(T) where T: Iterator<Item: ?Sized>; //~ ERROR this relaxed bound is not permitted here

trait Tr: ?Sized {} //~ ERROR relaxed bounds are not permitted in supertrait bounds

// Test that relaxed `Sized` bounds are rejected in trait object types:
Expand Down
18 changes: 13 additions & 5 deletions tests/ui/unsized/relaxed-bounds-invalid-places.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,36 @@ LL | fn f() where T: ?Sized {}
|
= note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item

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

error: relaxed bounds are not permitted in supertrait bounds
--> $DIR/relaxed-bounds-invalid-places.rs:25:11
--> $DIR/relaxed-bounds-invalid-places.rs:29:11
|
LL | trait Tr: ?Sized {}
| ^^^^^^
|
= note: traits are `?Sized` by default

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

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

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

error: aborting due to 11 previous errors
error: aborting due to 12 previous errors

Loading