Skip to content

Commit e564a69

Browse files
committed
Reword diagnostic about relaxing non-Sized bound
* The phrasing "only does something for" made sense back when this diagnostic was a (hard) warning. Now however, it's simply a hard error and thus completely rules out. * The primary message was way too long * The new wording more closely mirrors the wording we use for applying other bound modifiers (like `const` and `async`) to incompatible traits. * "all other traits are not bound by default" is no longer accurate under Sized Hierarchy. E.g., traits and assoc tys are (currently) bounded by `MetaSized` by default but can't be relaxed using `?MetaSized` (instead, you relax it by adding `PointeeSized`). * I've decided against adding any diagnositic notes or suggestions for now like "trait `Trait` can't be relaxed as it's not bound by default" /which would be incorrect for `MetaSized` and assoc tys as mentioned above) or "consider changing `?MetaSized` to `PointeeSized`" as the Sized Hierarchy impl is still WIP)
1 parent 63dce2e commit e564a69

24 files changed

+118
-117
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,17 @@ fn search_bounds_for<'tcx>(
8585
}
8686
}
8787

88-
fn collect_unbounds<'tcx>(
88+
fn collect_relaxed_bounds<'tcx>(
8989
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
9090
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
9191
) -> SmallVec<[&'tcx PolyTraitRef<'tcx>; 1]> {
92-
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
92+
let mut relaxed_bounds: SmallVec<[_; 1]> = SmallVec::new();
9393
search_bounds_for(hir_bounds, self_ty_where_predicates, |ptr| {
9494
if matches!(ptr.modifiers.polarity, hir::BoundPolarity::Maybe(_)) {
95-
unbounds.push(ptr);
95+
relaxed_bounds.push(ptr);
9696
}
9797
});
98-
unbounds
98+
relaxed_bounds
9999
}
100100

101101
fn collect_bounds<'a, 'tcx>(
@@ -204,9 +204,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
204204
return;
205205
}
206206
} else {
207-
// Report invalid unbounds on sizedness-bounded generic parameters.
208-
let unbounds = collect_unbounds(hir_bounds, self_ty_where_predicates);
209-
self.check_and_report_invalid_unbounds_on_param(unbounds);
207+
// Report invalid relaxed bounds.
208+
// FIXME(more_maybe_bounds): This validation function is only called in contexts where
209+
// we perform "sized elaboration". This means, it doesn't get called for e.g.,
210+
// trait object types or supertrait bounds!
211+
// Ideally, we would do these checks in `Self::lower_poly_trait_ref`!
212+
let bounds = collect_relaxed_bounds(hir_bounds, self_ty_where_predicates);
213+
self.check_and_report_invalid_relaxed_bounds(bounds);
210214
}
211215

212216
let collected = collect_sizedness_bounds(tcx, hir_bounds, self_ty_where_predicates, span);

compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_errors::{
88
};
99
use rustc_hir::def::{CtorOf, DefKind, Res};
1010
use rustc_hir::def_id::DefId;
11-
use rustc_hir::{self as hir, HirId, LangItem, PolyTraitRef};
11+
use rustc_hir::{self as hir, HirId, PolyTraitRef};
1212
use rustc_middle::bug;
1313
use rustc_middle::ty::fast_reject::{TreatParams, simplify_type};
1414
use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
@@ -34,26 +34,24 @@ use crate::fluent_generated as fluent;
3434
use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer};
3535

3636
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
37-
/// Check for multiple relaxed default bounds and relaxed bounds of non-sizedness traits.
38-
pub(crate) fn check_and_report_invalid_unbounds_on_param(
37+
/// Check for duplicate relaxed bounds and relaxed bounds of non-default traits.
38+
pub(crate) fn check_and_report_invalid_relaxed_bounds(
3939
&self,
40-
unbounds: SmallVec<[&PolyTraitRef<'_>; 1]>,
40+
relaxed_bounds: SmallVec<[&PolyTraitRef<'_>; 1]>,
4141
) {
4242
let tcx = self.tcx();
4343

44-
let sized_did = tcx.require_lang_item(LangItem::Sized, DUMMY_SP);
45-
4644
let mut unique_bounds = FxIndexSet::default();
4745
let mut seen_repeat = false;
48-
for unbound in &unbounds {
49-
if let Res::Def(DefKind::Trait, unbound_def_id) = unbound.trait_ref.path.res {
50-
seen_repeat |= !unique_bounds.insert(unbound_def_id);
46+
for bound in &relaxed_bounds {
47+
if let Res::Def(DefKind::Trait, trait_def_id) = bound.trait_ref.path.res {
48+
seen_repeat |= !unique_bounds.insert(trait_def_id);
5149
}
5250
}
5351

54-
if unbounds.len() > 1 {
52+
if relaxed_bounds.len() > 1 {
5553
let err = errors::MultipleRelaxedDefaultBounds {
56-
spans: unbounds.iter().map(|ptr| ptr.span).collect(),
54+
spans: relaxed_bounds.iter().map(|ptr| ptr.span).collect(),
5755
};
5856

5957
if seen_repeat {
@@ -63,24 +61,23 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
6361
};
6462
}
6563

66-
for unbound in unbounds {
67-
if let Res::Def(DefKind::Trait, did) = unbound.trait_ref.path.res
68-
&& ((did == sized_did) || tcx.is_default_trait(did))
64+
let sized_def_id = tcx.require_lang_item(hir::LangItem::Sized, DUMMY_SP);
65+
66+
for bound in relaxed_bounds {
67+
if let Res::Def(DefKind::Trait, def_id) = bound.trait_ref.path.res
68+
&& (def_id == sized_def_id || tcx.is_default_trait(def_id))
6969
{
7070
continue;
7171
}
72-
73-
let unbound_traits = match tcx.sess.opts.unstable_opts.experimental_default_bounds {
74-
true => "`?Sized` and `experimental_default_bounds`",
75-
false => "`?Sized`",
76-
};
7772
self.dcx().span_err(
78-
unbound.span,
79-
format!(
80-
"relaxing a default bound only does something for {}; all other traits are \
81-
not bound by default",
82-
unbound_traits
83-
),
73+
bound.span,
74+
if tcx.sess.opts.unstable_opts.experimental_default_bounds
75+
|| tcx.features().more_maybe_bounds()
76+
{
77+
"bound modifier `?` can only be applied to default traits like `Sized`"
78+
} else {
79+
"bound modifier `?` can only be applied to `Sized`"
80+
},
8481
);
8582
}
8683
}

tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
99
//~^ ERROR relaxed bounds are not permitted in trait object types
1010
fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
1111
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
12-
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
13-
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
12+
//~| ERROR bound modifier `?` can only be applied to `Sized`
13+
//~| ERROR bound modifier `?` can only be applied to `Sized`
1414

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

2222
fn main() {}

tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
3535
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
3636
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
3737

38-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
38+
error: bound modifier `?` can only be applied to `Sized`
3939
--> $DIR/feature-gate-more-maybe-bounds.rs:10:11
4040
|
4141
LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
4242
| ^^^^^^^
4343

44-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
44+
error: bound modifier `?` can only be applied to `Sized`
4545
--> $DIR/feature-gate-more-maybe-bounds.rs:10:21
4646
|
4747
LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
@@ -53,13 +53,13 @@ error[E0203]: type parameter has more than one relaxed default bound, only one i
5353
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
5454
| ^^^^^^ ^^^^^^
5555

56-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
56+
error: bound modifier `?` can only be applied to `Sized`
5757
--> $DIR/feature-gate-more-maybe-bounds.rs:17:11
5858
|
5959
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
6060
| ^^^^^^
6161

62-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
62+
error: bound modifier `?` can only be applied to `Sized`
6363
--> $DIR/feature-gate-more-maybe-bounds.rs:17:20
6464
|
6565
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}

tests/ui/impl-trait/opt-out-bound-not-satisfied.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
44
use std::future::Future;
55
fn foo() -> impl ?Future<Output = impl Send> {
6-
//~^ ERROR: relaxing a default bound only does something for `?Sized`
7-
//~| ERROR: relaxing a default bound only does something for `?Sized`
6+
//~^ ERROR: bound modifier `?` can only be applied to `Sized`
7+
//~| ERROR: bound modifier `?` can only be applied to `Sized`
88
()
99
}
1010

tests/ui/impl-trait/opt-out-bound-not-satisfied.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
1+
error: bound modifier `?` can only be applied to `Sized`
22
--> $DIR/opt-out-bound-not-satisfied.rs:5:18
33
|
44
LL | fn foo() -> impl ?Future<Output = impl Send> {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
66

7-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
7+
error: bound modifier `?` can only be applied to `Sized`
88
--> $DIR/opt-out-bound-not-satisfied.rs:5:18
99
|
1010
LL | fn foo() -> impl ?Future<Output = impl Send> {

tests/ui/issues/issue-37534.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
struct Foo<T: ?Hash> {}
22
//~^ ERROR expected trait, found derive macro `Hash`
3-
//~| ERROR relaxing a default bound only does something for `?Sized`
3+
//~| ERROR bound modifier `?` can only be applied to `Sized`
44

55
fn main() {}

tests/ui/issues/issue-37534.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ help: consider importing this trait instead
99
LL + use std::hash::Hash;
1010
|
1111

12-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
12+
error: bound modifier `?` can only be applied to `Sized`
1313
--> $DIR/issue-37534.rs:1:15
1414
|
1515
LL | struct Foo<T: ?Hash> {}

tests/ui/issues/issue-87199.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66

77
// Check that these function definitions only emit warnings, not errors
88
fn arg<T: ?Send>(_: T) {}
9-
//~^ ERROR: relaxing a default bound only does something for `?Sized`
9+
//~^ ERROR: bound modifier `?` can only be applied to `Sized`
1010
fn ref_arg<T: ?Send>(_: &T) {}
11-
//~^ ERROR: relaxing a default bound only does something for `?Sized`
11+
//~^ ERROR: bound modifier `?` can only be applied to `Sized`
1212
fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
13-
//~^ ERROR: relaxing a default bound only does something for `?Sized`
14-
//~| ERROR: relaxing a default bound only does something for `?Sized`
13+
//~^ ERROR: bound modifier `?` can only be applied to `Sized`
14+
//~| ERROR: bound modifier `?` can only be applied to `Sized`
1515

1616
// Check that there's no `?Sized` relaxation!
1717
fn main() {

tests/ui/issues/issue-87199.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
1+
error: bound modifier `?` can only be applied to `Sized`
22
--> $DIR/issue-87199.rs:8:11
33
|
44
LL | fn arg<T: ?Send>(_: T) {}
55
| ^^^^^
66

7-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
7+
error: bound modifier `?` can only be applied to `Sized`
88
--> $DIR/issue-87199.rs:10:15
99
|
1010
LL | fn ref_arg<T: ?Send>(_: &T) {}
1111
| ^^^^^
1212

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

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

tests/ui/sized-hierarchy/default-bound.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ fn neg_sized<T: ?Sized>() {}
1414
fn metasized<T: MetaSized>() {}
1515

1616
fn neg_metasized<T: ?MetaSized>() {}
17-
//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
17+
//~^ ERROR bound modifier `?` can only be applied to `Sized`
1818

1919

2020
fn pointeesized<T: PointeeSized>() { }
2121

2222
fn neg_pointeesized<T: ?PointeeSized>() { }
23-
//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
23+
//~^ ERROR bound modifier `?` can only be applied to `Sized`
2424

2525

2626
fn main() {

tests/ui/sized-hierarchy/default-bound.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
1+
error: bound modifier `?` can only be applied to `Sized`
22
--> $DIR/default-bound.rs:16:21
33
|
44
LL | fn neg_metasized<T: ?MetaSized>() {}
55
| ^^^^^^^^^^
66

7-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
7+
error: bound modifier `?` can only be applied to `Sized`
88
--> $DIR/default-bound.rs:22:24
99
|
1010
LL | fn neg_pointeesized<T: ?PointeeSized>() { }

tests/ui/trait-bounds/maybe-bound-has-path-args.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ trait Trait {}
22

33
fn test<T: ?self::<i32>::Trait>() {}
44
//~^ ERROR type arguments are not allowed on module `maybe_bound_has_path_args`
5-
//~| ERROR relaxing a default bound only does something for `?Sized`
5+
//~| ERROR bound modifier `?` can only be applied to `Sized`
66

77
fn main() {}

tests/ui/trait-bounds/maybe-bound-has-path-args.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
1+
error: bound modifier `?` can only be applied to `Sized`
22
--> $DIR/maybe-bound-has-path-args.rs:3:12
33
|
44
LL | fn test<T: ?self::<i32>::Trait>() {}

tests/ui/trait-bounds/maybe-bound-with-assoc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ trait HasAssoc {
22
type Assoc;
33
}
44
fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
5-
//~^ ERROR relaxing a default bound
5+
//~^ ERROR bound modifier `?` can only be applied to `Sized`
66

77
trait NoAssoc {}
88
fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
9-
//~^ ERROR relaxing a default bound
9+
//~^ ERROR bound modifier `?` can only be applied to `Sized`
1010
//~| ERROR associated type `Missing` not found for `NoAssoc`
1111

1212
fn main() {}

tests/ui/trait-bounds/maybe-bound-with-assoc.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
1+
error: bound modifier `?` can only be applied to `Sized`
22
--> $DIR/maybe-bound-with-assoc.rs:4:16
33
|
44
LL | fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
55
| ^^^^^^^^^^^^^^^^^^^^^
66

7-
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
7+
error: bound modifier `?` can only be applied to `Sized`
88
--> $DIR/maybe-bound-with-assoc.rs:8:15
99
|
1010
LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// FIXME(more_maybe_bounds): This used to be a check-pass test before rustc started to reject
2+
// relaxed bounds of *non-default* traits. Thefore, the original test intention has been lost.
3+
#![feature(auto_traits, more_maybe_bounds, negative_impls)]
4+
5+
trait Trait1 {}
6+
auto trait Trait2 {}
7+
8+
trait Trait3 : ?Trait1 {}
9+
trait Trait4 where Self: Trait1 {}
10+
11+
fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {}
12+
fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
13+
//~^ ERROR bound modifier `?` can only be applied to default traits like `Sized`
14+
//~| ERROR bound modifier `?` can only be applied to default traits like `Sized`
15+
//~| ERROR bound modifier `?` can only be applied to default traits like `Sized`
16+
17+
struct S;
18+
impl !Trait2 for S {}
19+
impl Trait1 for S {}
20+
impl Trait3 for S {}
21+
22+
fn main() {
23+
foo(Box::new(S));
24+
bar(&S);
25+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: bound modifier `?` can only be applied to default traits like `Sized`
2+
--> $DIR/more_maybe_bounds.rs:12:20
3+
|
4+
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
5+
| ^^^^^^^
6+
7+
error: bound modifier `?` can only be applied to default traits like `Sized`
8+
--> $DIR/more_maybe_bounds.rs:12:30
9+
|
10+
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
11+
| ^^^^^^^
12+
13+
error: bound modifier `?` can only be applied to default traits like `Sized`
14+
--> $DIR/more_maybe_bounds.rs:12:40
15+
|
16+
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
17+
| ^^^^^^^
18+
19+
error: aborting due to 3 previous errors
20+

tests/ui/traits/maybe-polarity-pass.rs

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

0 commit comments

Comments
 (0)