From 690a8a6dfd7a0bff4482826a0af885c3690cb0f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 16 Oct 2025 19:53:29 +0200 Subject: [PATCH] Tweak diagnostics for relaxed bounds in invalid positions --- compiler/rustc_ast_lowering/src/lib.rs | 46 +++++++++---------- .../feature-gate-more-maybe-bounds.stderr | 2 +- .../parser/trait-object-trait-parens.stderr | 6 +++ .../sized-hierarchy/default-supertrait.stderr | 2 +- .../ui/trait-bounds/more_maybe_bounds.stderr | 6 +-- .../traits/wf-object/only-maybe-bound.stderr | 2 + .../relaxed-bounds-invalid-places.stderr | 20 +++++--- 7 files changed, 49 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4e2243e87873..5968596dacce 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2103,33 +2103,33 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } RelaxedBoundPolicy::Forbidden(reason) => { + let gate = |context, subject| { + if self.tcx.features().more_maybe_bounds() { + return; + } + + let mut diag = self.dcx().struct_span_err( + span, + format!("relaxed bounds are not permitted in {context}"), + ); + if let Some(def_id) = trait_ref.trait_def_id() + && self.tcx.is_lang_item(def_id, hir::LangItem::Sized) + { + diag.note(format!( + "{subject} are not implicitly bounded by `Sized`, \ + so there is nothing to relax" + )); + } + diag.emit(); + }; + match reason { RelaxedBoundForbiddenReason::TraitObjectTy => { - if self.tcx.features().more_maybe_bounds() { - return; - } - - self.dcx().span_err( - span, - "relaxed bounds are not permitted in trait object types", - ); + gate("trait object types", "trait object types"); return; } RelaxedBoundForbiddenReason::SuperTrait => { - if self.tcx.features().more_maybe_bounds() { - return; - } - - let mut diag = self.dcx().struct_span_err( - span, - "relaxed bounds are not permitted in supertrait bounds", - ); - if let Some(def_id) = trait_ref.trait_def_id() - && self.tcx.is_lang_item(def_id, hir::LangItem::Sized) - { - diag.note("traits are `?Sized` by default"); - } - diag.emit(); + gate("supertrait bounds", "traits"); return; } RelaxedBoundForbiddenReason::AssocTyBounds @@ -2142,7 +2142,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .struct_span_err(span, "this relaxed bound is not permitted here") .with_note( "in this context, relaxed bounds are only allowed on \ - type parameters defined by the closest item", + type parameters defined on the closest item", ) .emit(); } diff --git a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr index da6ad5f16e20..092655b0f53a 100644 --- a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr @@ -10,7 +10,7 @@ error: this relaxed bound is not permitted here LL | trait Trait4 where Self: ?Trait1 {} | ^^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: relaxed bounds are not permitted in trait object types --> $DIR/feature-gate-more-maybe-bounds.rs:8:28 diff --git a/tests/ui/parser/trait-object-trait-parens.stderr b/tests/ui/parser/trait-object-trait-parens.stderr index f498d7d36bba..c43ca23c4885 100644 --- a/tests/ui/parser/trait-object-trait-parens.stderr +++ b/tests/ui/parser/trait-object-trait-parens.stderr @@ -3,18 +3,24 @@ error: relaxed bounds are not permitted in trait object types | LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; | ^^^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax error: relaxed bounds are not permitted in trait object types --> $DIR/trait-object-trait-parens.rs:13:16 | LL | let _: Box Trait<'a>) + (Obj)>; | ^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax error: relaxed bounds are not permitted in trait object types --> $DIR/trait-object-trait-parens.rs:18:44 | LL | let _: Box Trait<'a> + (Obj) + (?Sized)>; | ^^^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax warning: trait objects without an explicit `dyn` are deprecated --> $DIR/trait-object-trait-parens.rs:8:16 diff --git a/tests/ui/sized-hierarchy/default-supertrait.stderr b/tests/ui/sized-hierarchy/default-supertrait.stderr index f5589d6e279c..a4ade7fb8394 100644 --- a/tests/ui/sized-hierarchy/default-supertrait.stderr +++ b/tests/ui/sized-hierarchy/default-supertrait.stderr @@ -4,7 +4,7 @@ error: relaxed bounds are not permitted in supertrait bounds LL | trait NegSized: ?Sized { } | ^^^^^^ | - = note: traits are `?Sized` by default + = note: traits are not implicitly bounded by `Sized`, so there is nothing to relax error: relaxed bounds are not permitted in supertrait bounds --> $DIR/default-supertrait.rs:13:21 diff --git a/tests/ui/trait-bounds/more_maybe_bounds.stderr b/tests/ui/trait-bounds/more_maybe_bounds.stderr index 0d78cfd58204..b8782c560ad8 100644 --- a/tests/ui/trait-bounds/more_maybe_bounds.stderr +++ b/tests/ui/trait-bounds/more_maybe_bounds.stderr @@ -4,7 +4,7 @@ error: this relaxed bound is not permitted here LL | fn baz() where T: Iterator {} | ^^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: this relaxed bound is not permitted here --> $DIR/more_maybe_bounds.rs:29:21 @@ -12,7 +12,7 @@ error: this relaxed bound is not permitted here LL | fn f() where T: ?Trait1 {} | ^^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: this relaxed bound is not permitted here --> $DIR/more_maybe_bounds.rs:35:34 @@ -20,7 +20,7 @@ error: this relaxed bound is not permitted here LL | struct S2(T) where for<'a> T: ?Trait5<'a>; | ^^^^^^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: bound modifier `?` can only be applied to default traits like `Sized` --> $DIR/more_maybe_bounds.rs:17:20 diff --git a/tests/ui/traits/wf-object/only-maybe-bound.stderr b/tests/ui/traits/wf-object/only-maybe-bound.stderr index 6ae4568c699a..3f02d5a8a0c8 100644 --- a/tests/ui/traits/wf-object/only-maybe-bound.stderr +++ b/tests/ui/traits/wf-object/only-maybe-bound.stderr @@ -3,6 +3,8 @@ error: relaxed bounds are not permitted in trait object types | LL | type _0 = dyn ?Sized; | ^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax error[E0224]: at least one trait is required for an object type --> $DIR/only-maybe-bound.rs:3:11 diff --git a/tests/ui/unsized/relaxed-bounds-invalid-places.stderr b/tests/ui/unsized/relaxed-bounds-invalid-places.stderr index d3f0535e2f0c..34f5cebeeaf1 100644 --- a/tests/ui/unsized/relaxed-bounds-invalid-places.stderr +++ b/tests/ui/unsized/relaxed-bounds-invalid-places.stderr @@ -4,7 +4,7 @@ error: this relaxed bound is not permitted here LL | struct S1(T) where (T): ?Sized; | ^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: this relaxed bound is not permitted here --> $DIR/relaxed-bounds-invalid-places.rs:8:27 @@ -12,7 +12,7 @@ error: this relaxed bound is not permitted here LL | struct S2(T) where u8: ?Sized; | ^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: this relaxed bound is not permitted here --> $DIR/relaxed-bounds-invalid-places.rs:10:35 @@ -20,7 +20,7 @@ error: this relaxed bound is not permitted here LL | struct S3(T) where &'static T: ?Sized; | ^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: this relaxed bound is not permitted here --> $DIR/relaxed-bounds-invalid-places.rs:14:34 @@ -28,7 +28,7 @@ error: this relaxed bound is not permitted here LL | struct S4(T) where for<'a> T: ?Trait<'a>; | ^^^^^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: this relaxed bound is not permitted here --> $DIR/relaxed-bounds-invalid-places.rs:22:21 @@ -36,7 +36,7 @@ error: this relaxed bound is not permitted here LL | fn f() where T: ?Sized {} | ^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: this relaxed bound is not permitted here --> $DIR/relaxed-bounds-invalid-places.rs:27:41 @@ -44,7 +44,7 @@ error: this relaxed bound is not permitted here LL | struct S6(T) where T: Iterator; | ^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: relaxed bounds are not permitted in supertrait bounds --> $DIR/relaxed-bounds-invalid-places.rs:29:11 @@ -52,25 +52,31 @@ error: relaxed bounds are not permitted in supertrait bounds LL | trait Tr: ?Sized {} | ^^^^^^ | - = note: traits are `?Sized` by default + = note: traits are not implicitly bounded by `Sized`, so there is nothing to relax error: relaxed bounds are not permitted in trait object types --> $DIR/relaxed-bounds-invalid-places.rs:33:20 | LL | type O1 = dyn Tr + ?Sized; | ^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax error: relaxed bounds are not permitted in trait object types --> $DIR/relaxed-bounds-invalid-places.rs:34:15 | LL | type O2 = dyn ?Sized + ?Sized + Tr; | ^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax error: relaxed bounds are not permitted in trait object types --> $DIR/relaxed-bounds-invalid-places.rs:34:24 | LL | type O2 = dyn ?Sized + ?Sized + Tr; | ^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax error: bound modifier `?` can only be applied to `Sized` --> $DIR/relaxed-bounds-invalid-places.rs:14:34