Skip to content

Reject ?Trait bounds in various places where we unconditionally warned since 1.0 #135841

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

Merged
merged 1 commit into from
Feb 13, 2025
Merged
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
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
seen_sized_unbound = true;
continue;
}
// There was a `?Trait` bound, but it was not `?Sized`; warn.
self.dcx().span_warn(
// There was a `?Trait` bound, but it was not `?Sized`
self.dcx().span_err(
unbound.span,
"relaxing a default bound only does something for `?Sized`; \
all other traits are not bound by default",
Comment on lines 108 to 109
Copy link
Member

@fmease fmease Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to block this PR on surface level things like phrasing, so feel free to ignore this and I'll submit this as a follow-up PR. I've never liked how this specific diagnostic is formulated, it's super verbose.

Now with this being a hard error this sentence doesn't quite make sense anymore. I'd rather see a message that's straight to the point like `?` can only be applied to `Sized` (similar to `~const` can only be applied to `#[const_trait]` traits or `async` bound modifier only allowed on `Fn`/`FnMut`/`FnOnce` traits) and defer any further explanations to diagnostic note/help messages if at all (cc error codes).

If we wanted to feel fancy we could provide a structured suggestion for removing the entire bound.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we do this as a follow-up

Expand Down
11 changes: 5 additions & 6 deletions tests/ui/diagnostic-flags/allow-non-lint-warnings.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// ignore-tidy-linelength
//! Check that `-A warnings` cli flag applies to non-lint warnings as well.
//!
//! This test tries to exercise that by checking that the "relaxing a default bound only does
//! something for `?Sized`; all other traits are not bound by default" non-lint warning (normally
//! This test tries to exercise that by checking that a non-lint warning (normally
//! warn-by-default) is suppressed if the `-A warnings` cli flag is passed.
//!
//! Take special note that `warnings` is a special pseudo lint group in relationship to non-lint
Expand All @@ -14,14 +13,14 @@
//! - Original impl PR: <https://github.com/rust-lang/rust/pull/21248>.
//! - RFC 507 "Release channels":
//! <https://github.com/rust-lang/rfcs/blob/c017755b9bfa0421570d92ba38082302e0f3ad4f/text/0507-release-channels.md>.
#![crate_type = "lib"]
#![feature(rustc_attrs)]

//@ revisions: without_flag with_flag

//@[with_flag] compile-flags: -Awarnings

//@ check-pass

pub trait Trait {}
pub fn f<T: ?Trait>() {}
//[without_flag]~^ WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
#[rustc_error(warn)]
fn main() {}
//[without_flag]~^ WARN unexpected annotation used with `#[rustc_error(...)]`!
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/allow-non-lint-warnings.rs:26:13
warning: unexpected annotation used with `#[rustc_error(...)]`!
--> $DIR/allow-non-lint-warnings.rs:25:1
|
LL | pub fn f<T: ?Trait>() {}
| ^^^^^^
LL | fn main() {}
| ^^^^^^^^^

warning: 1 warning emitted

8 changes: 4 additions & 4 deletions tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
//~^ ERROR `?Trait` is not permitted in trait object types
fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default

trait Trait {}
// Do not suggest `#![feature(more_maybe_bounds)]` for repetitions
fn baz<T: ?Trait + ?Trait>(_ : T) {}
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default

fn main() {}
10 changes: 5 additions & 5 deletions tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/feature-gate-more-maybe-bounds.rs:12:11
|
LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
| ^^^^^^^

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/feature-gate-more-maybe-bounds.rs:12:21
|
LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
Expand All @@ -53,19 +53,19 @@ error[E0203]: type parameter has more than one relaxed default bound, only one i
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
| ^^^^^^ ^^^^^^

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/feature-gate-more-maybe-bounds.rs:19:11
|
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
| ^^^^^^

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/feature-gate-more-maybe-bounds.rs:19:20
|
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
| ^^^^^^

error: aborting due to 5 previous errors; 4 warnings emitted
error: aborting due to 9 previous errors

Some errors have detailed explanations: E0203, E0658.
For more information about an error, try `rustc --explain E0203`.
11 changes: 11 additions & 0 deletions tests/ui/impl-trait/opt-out-bound-not-satisfied.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//! Regression test for ICE https://github.com/rust-lang/rust/issues/135730
//! This used

use std::future::Future;
fn foo() -> impl ?Future<Output = impl Send> {
//~^ ERROR: relaxing a default bound only does something for `?Sized`
//~| ERROR: relaxing a default bound only does something for `?Sized`
()
}

pub fn main() {}
16 changes: 16 additions & 0 deletions tests/ui/impl-trait/opt-out-bound-not-satisfied.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/opt-out-bound-not-satisfied.rs:5:18
|
LL | fn foo() -> impl ?Future<Output = impl Send> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/opt-out-bound-not-satisfied.rs:5:18
|
LL | fn foo() -> impl ?Future<Output = impl Send> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 2 previous errors

2 changes: 1 addition & 1 deletion tests/ui/issues/issue-37534.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
struct Foo<T: ?Hash> {}
//~^ ERROR expected trait, found derive macro `Hash`
//~| WARN relaxing a default bound only does something for `?Sized`
//~| ERROR relaxing a default bound only does something for `?Sized`

fn main() {}
4 changes: 2 additions & 2 deletions tests/ui/issues/issue-37534.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ help: consider importing this trait instead
LL + use std::hash::Hash;
|

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/issue-37534.rs:1:15
|
LL | struct Foo<T: ?Hash> {}
| ^^^^^

error: aborting due to 1 previous error; 1 warning emitted
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0404`.
8 changes: 4 additions & 4 deletions tests/ui/issues/issue-87199.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@

// Check that these function definitions only emit warnings, not errors
fn arg<T: ?Send>(_: T) {}
//~^ warning: relaxing a default bound only does something for `?Sized`
//~^ ERROR: relaxing a default bound only does something for `?Sized`
fn ref_arg<T: ?Send>(_: &T) {}
//~^ warning: relaxing a default bound only does something for `?Sized`
//~^ ERROR: relaxing a default bound only does something for `?Sized`
fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
//~^ warning: relaxing a default bound only does something for `?Sized`
//~| warning: relaxing a default bound only does something for `?Sized`
//~^ ERROR: relaxing a default bound only does something for `?Sized`
//~| ERROR: relaxing a default bound only does something for `?Sized`

// Check that there's no `?Sized` relaxation!
fn main() {
Expand Down
10 changes: 5 additions & 5 deletions tests/ui/issues/issue-87199.stderr
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/issue-87199.rs:8:11
|
LL | fn arg<T: ?Send>(_: T) {}
| ^^^^^

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/issue-87199.rs:10:15
|
LL | fn ref_arg<T: ?Send>(_: &T) {}
| ^^^^^

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/issue-87199.rs:12:40
|
LL | fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
| ^^^^^

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/issue-87199.rs:12:40
|
LL | fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
Expand All @@ -41,6 +41,6 @@ help: consider relaxing the implicit `Sized` restriction
LL | fn ref_arg<T: ?Send + ?Sized>(_: &T) {}
| ++++++++

error: aborting due to 1 previous error; 4 warnings emitted
error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0277`.
2 changes: 1 addition & 1 deletion tests/ui/trait-bounds/maybe-bound-has-path-args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ trait Trait {}

fn test<T: ?self::<i32>::Trait>() {}
//~^ ERROR type arguments are not allowed on module `maybe_bound_has_path_args`
//~| WARN relaxing a default bound only does something for `?Sized`
//~| ERROR relaxing a default bound only does something for `?Sized`

fn main() {}
4 changes: 2 additions & 2 deletions tests/ui/trait-bounds/maybe-bound-has-path-args.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-bound-has-path-args.rs:3:12
|
LL | fn test<T: ?self::<i32>::Trait>() {}
Expand All @@ -12,6 +12,6 @@ LL | fn test<T: ?self::<i32>::Trait>() {}
| |
| not allowed on module `maybe_bound_has_path_args`

error: aborting due to 1 previous error; 1 warning emitted
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0109`.
4 changes: 2 additions & 2 deletions tests/ui/trait-bounds/maybe-bound-with-assoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ trait HasAssoc {
type Assoc;
}
fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
//~^ WARN relaxing a default bound
//~^ ERROR relaxing a default bound

trait NoAssoc {}
fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
//~^ WARN relaxing a default bound
//~^ ERROR relaxing a default bound
//~| ERROR associated type `Missing` not found for `NoAssoc`

fn main() {}
6 changes: 3 additions & 3 deletions tests/ui/trait-bounds/maybe-bound-with-assoc.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-bound-with-assoc.rs:4:16
|
LL | fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
| ^^^^^^^^^^^^^^^^^^^^^

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-bound-with-assoc.rs:8:15
|
LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
Expand All @@ -16,6 +16,6 @@ error[E0220]: associated type `Missing` not found for `NoAssoc`
LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
| ^^^^^^^ associated type `Missing` not found

error: aborting due to 1 previous error; 2 warnings emitted
error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0220`.
8 changes: 3 additions & 5 deletions tests/ui/traits/maybe-polarity-pass.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//@ check-pass

#![feature(auto_traits)]
#![feature(more_maybe_bounds)]
#![feature(negative_impls)]
Expand All @@ -12,9 +10,9 @@ trait Trait4 where Self: Trait1 {}

fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {}
fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
//~^ WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default

struct S;
impl !Trait2 for S {}
Expand Down
14 changes: 7 additions & 7 deletions tests/ui/traits/maybe-polarity-pass.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-pass.rs:14:20
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-pass.rs:12:20
|
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
| ^^^^^^^

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-pass.rs:14:30
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-pass.rs:12:30
|
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
| ^^^^^^^

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-pass.rs:14:40
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-pass.rs:12:40
|
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
| ^^^^^^^

warning: 3 warnings emitted
error: aborting due to 3 previous errors

4 changes: 2 additions & 2 deletions tests/ui/traits/maybe-polarity-repeated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
trait Trait {}
fn foo<T: ?Trait + ?Trait>(_: T) {}
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default

fn main() {}
6 changes: 3 additions & 3 deletions tests/ui/traits/maybe-polarity-repeated.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ error[E0203]: type parameter has more than one relaxed default bound, only one i
LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
| ^^^^^^ ^^^^^^

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-repeated.rs:4:11
|
LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
| ^^^^^^

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-repeated.rs:4:20
|
LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
| ^^^^^^

error: aborting due to 1 previous error; 2 warnings emitted
error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0203`.
4 changes: 2 additions & 2 deletions tests/ui/unsized/maybe-bounds-where.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ trait Trait<'a> {}

struct S4<T>(T) where for<'a> T: ?Trait<'a>;
//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared
//~| WARN relaxing a default bound only does something for `?Sized`
//~| ERROR relaxing a default bound only does something for `?Sized`

struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
//~^ ERROR type parameter has more than one relaxed default bound
//~| WARN relaxing a default bound only does something for `?Sized`
//~| ERROR relaxing a default bound only does something for `?Sized`

impl<T> S1<T> {
fn f() where T: ?Sized {}
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/unsized/maybe-bounds-where.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ LL | fn f() where T: ?Sized {}
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-bounds-where.rs:12:34
|
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
Expand All @@ -58,13 +58,13 @@ LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-bounds-where.rs:16:33
|
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
| ^^^^^^^^^^^^^^^

error: aborting due to 6 previous errors; 2 warnings emitted
error: aborting due to 8 previous errors

Some errors have detailed explanations: E0203, E0658.
For more information about an error, try `rustc --explain E0203`.
Loading