From 1df99f22d3a1776b36fc00fc35626fd841f7242f Mon Sep 17 00:00:00 2001 From: León Orell Valerian Liehr Date: Wed, 18 Jun 2025 22:10:53 +0200 Subject: AST lowering: More robustly deal with relaxed bounds --- compiler/rustc_ast_lowering/src/lib.rs | 128 +++++++++++++++++++++++++++------ 1 file changed, 107 insertions(+), 21 deletions(-) (limited to 'compiler/rustc_ast_lowering/src/lib.rs') diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1c96a375035..d3d521e83b0 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -53,14 +53,14 @@ use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId}; use rustc_hir::lints::DelayedLint; use rustc_hir::{ - self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem, - LifetimeSource, LifetimeSyntax, ParamName, TraitCandidate, + self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource, + LifetimeSyntax, ParamName, TraitCandidate, }; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_macros::extension; use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; -use rustc_session::parse::add_feature_diagnostics; +use rustc_session::parse::{add_feature_diagnostics, feature_err}; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, DesugaringKind, Span}; use smallvec::SmallVec; @@ -281,6 +281,24 @@ impl ResolverAstLowering { } } +/// How relaxed bounds `?Trait` should be treated. +/// +/// Relaxed bounds should only be allowed in places where we later +/// (namely during HIR ty lowering) perform *sized elaboration*. +#[derive(Clone, Copy, Debug)] +enum RelaxedBoundPolicy<'a> { + Allowed, + AllowedIfOnTyParam(NodeId, &'a [ast::GenericParam]), + Forbidden(RelaxedBoundForbiddenReason), +} + +#[derive(Clone, Copy, Debug)] +enum RelaxedBoundForbiddenReason { + TraitObjectTy, + SuperTrait, + LateBoundVarsInScope, +} + /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree, /// and if so, what meaning it has. #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -1084,10 +1102,9 @@ 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 { - // Desugar `AssocTy: Bounds` into an assoc type binding where the - // later desugars into a trait predicate. - let bounds = self.lower_param_bounds(bounds, itctx); - + // FIXME(#135229): These should be forbidden! + let bounds = + self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx); hir::AssocItemConstraintKind::Bound { bounds } } } @@ -1216,6 +1233,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: t.span, parens: ast::Parens::No, }, + RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitObjectTy), itctx, ); let bounds = this.arena.alloc_from_iter([bound]); @@ -1271,7 +1289,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { parenthesized: hir::GenericArgsParentheses::No, span_ext: span, }); - let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args)); + let path = self.make_lang_item_qpath(hir::LangItem::Pin, span, Some(args)); hir::TyKind::Path(path) } TyKind::FnPtr(f) => { @@ -1332,7 +1350,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // takes care of rejecting invalid modifier combinations and // const trait bounds in trait object types. GenericBound::Trait(ty) => { - let trait_ref = this.lower_poly_trait_ref(ty, itctx); + let trait_ref = this.lower_poly_trait_ref( + ty, + RelaxedBoundPolicy::Forbidden( + RelaxedBoundForbiddenReason::TraitObjectTy, + ), + itctx, + ); Some(trait_ref) } GenericBound::Outlives(lifetime) => { @@ -1387,9 +1411,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } path } - ImplTraitContext::InBinding => { - hir::TyKind::TraitAscription(self.lower_param_bounds(bounds, itctx)) - } + ImplTraitContext::InBinding => hir::TyKind::TraitAscription( + self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx), + ), ImplTraitContext::FeatureGated(position, feature) => { let guar = self .tcx @@ -1505,7 +1529,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| { - this.lower_param_bounds(bounds, itctx) + this.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx) }) } @@ -1799,10 +1823,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_param_bound( &mut self, tpb: &GenericBound, + rbp: RelaxedBoundPolicy<'_>, itctx: ImplTraitContext, ) -> hir::GenericBound<'hir> { match tpb { - GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)), + GenericBound::Trait(p) => { + hir::GenericBound::Trait(self.lower_poly_trait_ref(p, rbp, itctx)) + } GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime( lifetime, LifetimeSource::OutlivesBound, @@ -2017,19 +2044,75 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { #[instrument(level = "debug", skip(self))] fn lower_poly_trait_ref( &mut self, - p: &PolyTraitRef, + PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef, + rbp: RelaxedBoundPolicy<'_>, itctx: ImplTraitContext, ) -> hir::PolyTraitRef<'hir> { let bound_generic_params = - self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params); - let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx); - let modifiers = self.lower_trait_bound_modifiers(p.modifiers); + self.lower_lifetime_binder(trait_ref.ref_id, bound_generic_params); + let trait_ref = self.lower_trait_ref(*modifiers, trait_ref, itctx); + let modifiers = self.lower_trait_bound_modifiers(*modifiers); + + if let ast::BoundPolarity::Maybe(_) = modifiers.polarity { + self.validate_relaxed_bound(trait_ref, *span, rbp); + } + hir::PolyTraitRef { bound_generic_params, modifiers, trait_ref, - span: self.lower_span(p.span), + span: self.lower_span(*span), + } + } + + fn validate_relaxed_bound( + &self, + trait_ref: hir::TraitRef<'_>, + span: Span, + rbp: RelaxedBoundPolicy<'_>, + ) { + let err = |message| feature_err(&self.tcx.sess, sym::more_maybe_bounds, span, message); + + match rbp { + RelaxedBoundPolicy::Allowed => return, + RelaxedBoundPolicy::AllowedIfOnTyParam(id, params) => { + if let Some(res) = self.resolver.get_partial_res(id).and_then(|r| r.full_res()) + && let Res::Def(DefKind::TyParam, def_id) = res + && params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id()) + { + return; + } + if self.tcx.features().more_maybe_bounds() { + return; + } + } + RelaxedBoundPolicy::Forbidden(reason) => { + if self.tcx.features().more_maybe_bounds() { + return; + } + + match reason { + RelaxedBoundForbiddenReason::TraitObjectTy => { + err("`?Trait` is not permitted in trait object types").emit(); + return; + } + RelaxedBoundForbiddenReason::SuperTrait => { + let mut diag = err("`?Trait` is not permitted in supertraits"); + 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(); + return; + } + RelaxedBoundForbiddenReason::LateBoundVarsInScope => {} + }; + } } + + err("`?Trait` bounds are only permitted at the point where a type parameter is declared") + .emit(); } fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> { @@ -2040,17 +2123,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_param_bounds( &mut self, bounds: &[GenericBound], + rbp: RelaxedBoundPolicy<'_>, itctx: ImplTraitContext, ) -> hir::GenericBounds<'hir> { - self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx)) + self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, rbp, itctx)) } fn lower_param_bounds_mut( &mut self, bounds: &[GenericBound], + rbp: RelaxedBoundPolicy<'_>, itctx: ImplTraitContext, ) -> impl Iterator> { - bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx)) + bounds.iter().map(move |bound| self.lower_param_bound(bound, rbp, itctx)) } #[instrument(level = "debug", skip(self), ret)] @@ -2084,6 +2169,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds, /* colon_span */ None, span, + RelaxedBoundPolicy::Allowed, ImplTraitContext::Universal, hir::PredicateOrigin::ImplTrait, ); -- cgit 1.4.1-3-g733a5 From 84ed70b69daa6865d3713d36fabad90a2fb96afd Mon Sep 17 00:00:00 2001 From: León Orell Valerian Liehr Date: Fri, 20 Jun 2025 21:39:19 +0200 Subject: Reword diagnostics about relaxed bounds in invalid contexts --- compiler/rustc_ast_lowering/src/lib.rs | 26 ++++++-- .../missing-associated_item_or_field_def_ids.rs | 2 +- ...missing-associated_item_or_field_def_ids.stderr | 8 +-- ...-getting-associated-items-of-undefined-trait.rs | 2 +- ...ting-associated-items-of-undefined-trait.stderr | 8 +-- .../feature-gate-more-maybe-bounds.rs | 8 +-- .../feature-gate-more-maybe-bounds.stderr | 34 ++++------- tests/ui/parser/trait-object-trait-parens.rs | 6 +- tests/ui/parser/trait-object-trait-parens.stderr | 18 ++---- tests/ui/sized-hierarchy/default-supertrait.rs | 6 +- tests/ui/sized-hierarchy/default-supertrait.stderr | 17 ++---- .../maybe-trait-bounds-forbidden-locations.rs | 18 ------ .../maybe-trait-bounds-forbidden-locations.stderr | 31 ---------- tests/ui/traits/wf-object/maybe-bound.rs | 18 ------ tests/ui/traits/wf-object/maybe-bound.stderr | 48 --------------- tests/ui/traits/wf-object/only-maybe-bound.rs | 2 +- tests/ui/traits/wf-object/only-maybe-bound.stderr | 8 +-- tests/ui/unsized/relaxed-bounds-invalid-places.rs | 35 ++++++----- .../unsized/relaxed-bounds-invalid-places.stderr | 70 ++++++++++++++-------- 19 files changed, 125 insertions(+), 240 deletions(-) delete mode 100644 tests/ui/traits/maybe-trait-bounds-forbidden-locations.rs delete mode 100644 tests/ui/traits/maybe-trait-bounds-forbidden-locations.stderr delete mode 100644 tests/ui/traits/wf-object/maybe-bound.rs delete mode 100644 tests/ui/traits/wf-object/maybe-bound.stderr (limited to 'compiler/rustc_ast_lowering/src/lib.rs') diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d3d521e83b0..533ee9bff54 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -60,7 +60,7 @@ use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_macros::extension; use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; -use rustc_session::parse::{add_feature_diagnostics, feature_err}; +use rustc_session::parse::add_feature_diagnostics; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, DesugaringKind, Span}; use smallvec::SmallVec; @@ -2071,7 +2071,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: Span, rbp: RelaxedBoundPolicy<'_>, ) { - let err = |message| feature_err(&self.tcx.sess, sym::more_maybe_bounds, span, message); + // Even though feature `more_maybe_bounds` bypasses the given policy and (currently) enables + // relaxed bounds in every conceivable position[^1], we don't want to advertise it to the user + // (via a feature gate) since it's super internal. Besides this, it'd be quite distracting. + // + // [^1]: Strictly speaking, this is incorrect (at the very least for `Sized`) because it's + // no longer fully consistent with default trait elaboration in HIR ty lowering. match rbp { RelaxedBoundPolicy::Allowed => return, @@ -2093,11 +2098,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { match reason { RelaxedBoundForbiddenReason::TraitObjectTy => { - err("`?Trait` is not permitted in trait object types").emit(); + self.dcx().span_err( + span, + "relaxed bounds are not permitted in trait object types", + ); return; } RelaxedBoundForbiddenReason::SuperTrait => { - let mut diag = err("`?Trait` is not permitted in supertraits"); + 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) { @@ -2111,7 +2122,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - err("`?Trait` bounds are only permitted at the point where a type parameter is declared") + self.dcx() + .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", + ) .emit(); } diff --git a/tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs b/tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs index 18c71e5c744..029ce7d0e7e 100644 --- a/tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs +++ b/tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs @@ -2,6 +2,6 @@ fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { //~^ ERROR expected trait, found associated function `Iterator::advance_by` - //~| ERROR `?Trait` is not permitted in trait object types + //~| ERROR relaxed bounds are not permitted in trait object types todo!() } diff --git a/tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr b/tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr index 6ec8e01c78d..ffe0b14a030 100644 --- a/tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr +++ b/tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr @@ -4,16 +4,12 @@ error[E0404]: expected trait, found associated function `Iterator::advance_by` LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a trait -error[E0658]: `?Trait` is not permitted in trait object types +error: relaxed bounds are not permitted in trait object types --> $DIR/missing-associated_item_or_field_def_ids.rs:3:29 | LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = 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 error: aborting due to 2 previous errors -Some errors have detailed explanations: E0404, E0658. -For more information about an error, try `rustc --explain E0404`. +For more information about this error, try `rustc --explain E0404`. diff --git a/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs b/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs index 9e0a86abb2e..bac4e608867 100644 --- a/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs +++ b/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs @@ -7,5 +7,5 @@ trait Tr { fn main() { let _: dyn Tr + ?Foo; //~^ ERROR: cannot find trait `Foo` in this scope - //~| ERROR: `?Trait` is not permitted in trait object types + //~| ERROR: relaxed bounds are not permitted in trait object types } diff --git a/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr b/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr index bd83c1a9ea8..3660fcece62 100644 --- a/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr +++ b/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr @@ -4,16 +4,12 @@ error[E0405]: cannot find trait `Foo` in this scope LL | let _: dyn Tr + ?Foo; | ^^^ not found in this scope -error[E0658]: `?Trait` is not permitted in trait object types +error: relaxed bounds are not permitted in trait object types --> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:21 | LL | let _: dyn Tr + ?Foo; | ^^^^^^^^^^^^^^^^ - | - = 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 error: aborting due to 2 previous errors -Some errors have detailed explanations: E0405, E0658. -For more information about an error, try `rustc --explain E0405`. +For more information about this error, try `rustc --explain E0405`. diff --git a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs index 6a832744e3e..3066967f87e 100644 --- a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs +++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs @@ -2,13 +2,11 @@ trait Trait1 {} auto trait Trait2 {} -trait Trait3: ?Trait1 {} -//~^ ERROR `?Trait` is not permitted in supertraits -trait Trait4 where Self: ?Trait1 {} -//~^ ERROR ?Trait` bounds are only permitted at the point where a type parameter is declared +trait Trait3: ?Trait1 {} //~ ERROR relaxed bounds are not permitted in supertrait bounds +trait Trait4 where Self: ?Trait1 {} //~ ERROR this relaxed bound is not permitted here fn foo(_: Box) {} -//~^ ERROR `?Trait` is not permitted in trait object types +//~^ ERROR relaxed bounds are not permitted in trait object types fn bar(_: T) {} //~^ ERROR type parameter has more than one relaxed default bound, only one is supported //~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default 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 f52532a035b..35b5b80d69e 100644 --- a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr @@ -1,32 +1,25 @@ -error[E0658]: `?Trait` is not permitted in supertraits +error: relaxed bounds are not permitted in supertrait bounds --> $DIR/feature-gate-more-maybe-bounds.rs:5:15 | LL | trait Trait3: ?Trait1 {} | ^^^^^^^ - | - = 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 -error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared - --> $DIR/feature-gate-more-maybe-bounds.rs:7:26 +error: this relaxed bound is not permitted here + --> $DIR/feature-gate-more-maybe-bounds.rs:6:26 | LL | trait Trait4 where Self: ?Trait1 {} | ^^^^^^^ | - = 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 + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/feature-gate-more-maybe-bounds.rs:10:28 +error: relaxed bounds are not permitted in trait object types + --> $DIR/feature-gate-more-maybe-bounds.rs:8:28 | LL | fn foo(_: Box) {} | ^^^^^^^ - | - = 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 error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/feature-gate-more-maybe-bounds.rs:12:11 + --> $DIR/feature-gate-more-maybe-bounds.rs:10:11 | LL | fn bar(_: T) {} | ^^^^^^^ ^^^^^^^ @@ -35,36 +28,35 @@ LL | fn bar(_: T) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date 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 + --> $DIR/feature-gate-more-maybe-bounds.rs:10:11 | LL | fn bar(_: T) {} | ^^^^^^^ 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 + --> $DIR/feature-gate-more-maybe-bounds.rs:10:21 | LL | fn bar(_: T) {} | ^^^^^^^ error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/feature-gate-more-maybe-bounds.rs:19:11 + --> $DIR/feature-gate-more-maybe-bounds.rs:17:11 | LL | fn baz(_ : T) {} | ^^^^^^ ^^^^^^ 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 + --> $DIR/feature-gate-more-maybe-bounds.rs:17:11 | LL | fn baz(_ : T) {} | ^^^^^^ 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 + --> $DIR/feature-gate-more-maybe-bounds.rs:17:20 | LL | fn baz(_ : T) {} | ^^^^^^ error: aborting due to 9 previous errors -Some errors have detailed explanations: E0203, E0658. -For more information about an error, try `rustc --explain E0203`. +For more information about this error, try `rustc --explain E0203`. diff --git a/tests/ui/parser/trait-object-trait-parens.rs b/tests/ui/parser/trait-object-trait-parens.rs index 438034bc38a..51f0e2de611 100644 --- a/tests/ui/parser/trait-object-trait-parens.rs +++ b/tests/ui/parser/trait-object-trait-parens.rs @@ -6,17 +6,17 @@ fn f Trait<'a>)>() {} fn main() { let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; - //~^ ERROR `?Trait` is not permitted in trait object types + //~^ ERROR relaxed bounds are not permitted in trait object types //~| ERROR only auto traits can be used as additional traits //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition let _: Box Trait<'a>) + (Obj)>; - //~^ ERROR `?Trait` is not permitted in trait object types + //~^ ERROR relaxed bounds are not permitted in trait object types //~| ERROR only auto traits can be used as additional traits //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition let _: Box Trait<'a> + (Obj) + (?Sized)>; - //~^ ERROR `?Trait` is not permitted in trait object types + //~^ ERROR relaxed bounds are not permitted in trait object types //~| ERROR only auto traits can be used as additional traits //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition diff --git a/tests/ui/parser/trait-object-trait-parens.stderr b/tests/ui/parser/trait-object-trait-parens.stderr index d75352b6811..26d388f8779 100644 --- a/tests/ui/parser/trait-object-trait-parens.stderr +++ b/tests/ui/parser/trait-object-trait-parens.stderr @@ -1,29 +1,20 @@ -error[E0658]: `?Trait` is not permitted in trait object types +error: relaxed bounds are not permitted in trait object types --> $DIR/trait-object-trait-parens.rs:8:24 | LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; | ^^^^^^^^ - | - = 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 -error[E0658]: `?Trait` is not permitted in trait object types +error: relaxed bounds are not permitted in trait object types --> $DIR/trait-object-trait-parens.rs:13:16 | LL | let _: Box Trait<'a>) + (Obj)>; | ^^^^^^ - | - = 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 -error[E0658]: `?Trait` is not permitted in trait object types +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)>; | ^^^^^^^^ - | - = 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: trait objects without an explicit `dyn` are deprecated --> $DIR/trait-object-trait-parens.rs:8:16 @@ -100,5 +91,4 @@ LL | let _: Box Trait<'a> + (Obj) + (?Sized)>; error: aborting due to 6 previous errors; 3 warnings emitted -Some errors have detailed explanations: E0225, E0658. -For more information about an error, try `rustc --explain E0225`. +For more information about this error, try `rustc --explain E0225`. diff --git a/tests/ui/sized-hierarchy/default-supertrait.rs b/tests/ui/sized-hierarchy/default-supertrait.rs index b25acf9e6ea..ab3b28e84db 100644 --- a/tests/ui/sized-hierarchy/default-supertrait.rs +++ b/tests/ui/sized-hierarchy/default-supertrait.rs @@ -6,18 +6,18 @@ use std::marker::{MetaSized, PointeeSized}; trait Sized_: Sized { } trait NegSized: ?Sized { } -//~^ ERROR `?Trait` is not permitted in supertraits +//~^ ERROR relaxed bounds are not permitted in supertrait bounds trait MetaSized_: MetaSized { } trait NegMetaSized: ?MetaSized { } -//~^ ERROR `?Trait` is not permitted in supertraits +//~^ ERROR relaxed bounds are not permitted in supertrait bounds trait PointeeSized_: PointeeSized { } trait NegPointeeSized: ?PointeeSized { } -//~^ ERROR `?Trait` is not permitted in supertraits +//~^ ERROR relaxed bounds are not permitted in supertrait bounds trait Bare {} diff --git a/tests/ui/sized-hierarchy/default-supertrait.stderr b/tests/ui/sized-hierarchy/default-supertrait.stderr index 0cb4f346a63..f5589d6e279 100644 --- a/tests/ui/sized-hierarchy/default-supertrait.stderr +++ b/tests/ui/sized-hierarchy/default-supertrait.stderr @@ -1,30 +1,22 @@ -error[E0658]: `?Trait` is not permitted in supertraits +error: relaxed bounds are not permitted in supertrait bounds --> $DIR/default-supertrait.rs:8:17 | LL | trait NegSized: ?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 = note: traits are `?Sized` by default -error[E0658]: `?Trait` is not permitted in supertraits +error: relaxed bounds are not permitted in supertrait bounds --> $DIR/default-supertrait.rs:13:21 | LL | trait NegMetaSized: ?MetaSized { } | ^^^^^^^^^^ - | - = 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 -error[E0658]: `?Trait` is not permitted in supertraits +error: relaxed bounds are not permitted in supertrait bounds --> $DIR/default-supertrait.rs:19:24 | LL | trait NegPointeeSized: ?PointeeSized { } | ^^^^^^^^^^^^^ - | - = 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 error[E0277]: the size for values of type `T` cannot be known --> $DIR/default-supertrait.rs:52:38 @@ -119,5 +111,4 @@ LL | fn with_bare_trait() { error: aborting due to 9 previous errors -Some errors have detailed explanations: E0277, E0658. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/maybe-trait-bounds-forbidden-locations.rs b/tests/ui/traits/maybe-trait-bounds-forbidden-locations.rs deleted file mode 100644 index 04963c98765..00000000000 --- a/tests/ui/traits/maybe-trait-bounds-forbidden-locations.rs +++ /dev/null @@ -1,18 +0,0 @@ -//! Test that ?Trait bounds are forbidden in supertraits and trait object types. -//! -//! While `?Sized` and other maybe bounds are allowed in type parameter bounds and where clauses, -//! they are explicitly forbidden in certain syntactic positions: -//! - As supertraits in trait definitions -//! - In trait object type expressions -//! -//! See https://github.com/rust-lang/rust/issues/20503 - -trait Tr: ?Sized {} -//~^ ERROR `?Trait` is not permitted in supertraits - -type A1 = dyn Tr + (?Sized); -//~^ ERROR `?Trait` is not permitted in trait object types -type A2 = dyn for<'a> Tr + (?Sized); -//~^ ERROR `?Trait` is not permitted in trait object types - -fn main() {} diff --git a/tests/ui/traits/maybe-trait-bounds-forbidden-locations.stderr b/tests/ui/traits/maybe-trait-bounds-forbidden-locations.stderr deleted file mode 100644 index 5c4100d0e26..00000000000 --- a/tests/ui/traits/maybe-trait-bounds-forbidden-locations.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0658]: `?Trait` is not permitted in supertraits - --> $DIR/maybe-trait-bounds-forbidden-locations.rs:10:11 - | -LL | trait Tr: ?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 - = note: traits are `?Sized` by default - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-trait-bounds-forbidden-locations.rs:13:20 - | -LL | type A1 = dyn Tr + (?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 - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-trait-bounds-forbidden-locations.rs:15:28 - | -LL | type A2 = dyn for<'a> Tr + (?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 - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/wf-object/maybe-bound.rs b/tests/ui/traits/wf-object/maybe-bound.rs deleted file mode 100644 index 17771e976ef..00000000000 --- a/tests/ui/traits/wf-object/maybe-bound.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Test that `dyn ... + ?Sized + ...` is okay (though `?Sized` has no effect in trait objects). - -trait Foo {} - -type _0 = dyn ?Sized + Foo; -//~^ ERROR `?Trait` is not permitted in trait object types - -type _1 = dyn Foo + ?Sized; -//~^ ERROR `?Trait` is not permitted in trait object types - -type _2 = dyn Foo + ?Sized + ?Sized; -//~^ ERROR `?Trait` is not permitted in trait object types -//~| ERROR `?Trait` is not permitted in trait object types - -type _3 = dyn ?Sized + Foo; -//~^ ERROR `?Trait` is not permitted in trait object types - -fn main() {} diff --git a/tests/ui/traits/wf-object/maybe-bound.stderr b/tests/ui/traits/wf-object/maybe-bound.stderr deleted file mode 100644 index be7afabd0d0..00000000000 --- a/tests/ui/traits/wf-object/maybe-bound.stderr +++ /dev/null @@ -1,48 +0,0 @@ -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-bound.rs:5:15 - | -LL | type _0 = dyn ?Sized + Foo; - | ^^^^^^ - | - = 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 - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-bound.rs:8:21 - | -LL | type _1 = dyn Foo + ?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 - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-bound.rs:11:21 - | -LL | type _2 = dyn Foo + ?Sized + ?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 - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-bound.rs:11:30 - | -LL | type _2 = dyn Foo + ?Sized + ?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 - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-bound.rs:15:15 - | -LL | type _3 = dyn ?Sized + Foo; - | ^^^^^^ - | - = 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 - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/wf-object/only-maybe-bound.rs b/tests/ui/traits/wf-object/only-maybe-bound.rs index 3e6db3e997c..96360e0331c 100644 --- a/tests/ui/traits/wf-object/only-maybe-bound.rs +++ b/tests/ui/traits/wf-object/only-maybe-bound.rs @@ -2,6 +2,6 @@ type _0 = dyn ?Sized; //~^ ERROR at least one trait is required for an object type [E0224] -//~| ERROR ?Trait` is not permitted in trait object types +//~| ERROR relaxed bounds are not permitted in trait object types fn main() {} diff --git a/tests/ui/traits/wf-object/only-maybe-bound.stderr b/tests/ui/traits/wf-object/only-maybe-bound.stderr index 26269476eaa..6ae4568c699 100644 --- a/tests/ui/traits/wf-object/only-maybe-bound.stderr +++ b/tests/ui/traits/wf-object/only-maybe-bound.stderr @@ -1,11 +1,8 @@ -error[E0658]: `?Trait` is not permitted in trait object types +error: relaxed bounds are not permitted in trait object types --> $DIR/only-maybe-bound.rs:3:15 | LL | type _0 = dyn ?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 error[E0224]: at least one trait is required for an object type --> $DIR/only-maybe-bound.rs:3:11 @@ -15,5 +12,4 @@ LL | type _0 = dyn ?Sized; error: aborting due to 2 previous errors -Some errors have detailed explanations: E0224, E0658. -For more information about an error, try `rustc --explain E0224`. +For more information about this error, try `rustc --explain E0224`. diff --git a/tests/ui/unsized/relaxed-bounds-invalid-places.rs b/tests/ui/unsized/relaxed-bounds-invalid-places.rs index ce3f35608be..e9f39d5f211 100644 --- a/tests/ui/unsized/relaxed-bounds-invalid-places.rs +++ b/tests/ui/unsized/relaxed-bounds-invalid-places.rs @@ -1,19 +1,18 @@ -// Test that relaxed bounds can only be placed on type parameters defined by the closest item -// (ignoring relaxed bounds inside `impl Trait` and in associated type defs here). +// Test various places where relaxed bounds are not permitted. +// +// Relaxed bounds are only permitted inside impl-Trait, assoc ty item bounds and +// on type params defined by the closest item. -struct S1(T) where (T): ?Sized; -//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared +struct S1(T) where (T): ?Sized; //~ ERROR this relaxed bound is not permitted here -struct S2(T) where u8: ?Sized; -//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared +struct S2(T) where u8: ?Sized; //~ ERROR this relaxed bound is not permitted here -struct S3(T) where &'static T: ?Sized; -//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared +struct S3(T) where &'static T: ?Sized; //~ ERROR this relaxed bound is not permitted here trait Trait<'a> {} struct S4(T) where for<'a> T: ?Trait<'a>; -//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared +//~^ ERROR this relaxed bound is not permitted here //~| ERROR relaxing a default bound only does something for `?Sized` struct S5(*const T) where T: ?Trait<'static> + ?Sized; @@ -21,11 +20,17 @@ struct S5(*const T) where T: ?Trait<'static> + ?Sized; //~| ERROR relaxing a default bound only does something for `?Sized` impl S1 { - fn f() where T: ?Sized {} - //~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared + fn f() where T: ?Sized {} //~ ERROR this relaxed bound is not permitted here } -fn main() { - let u = vec![1, 2, 3]; - let _s: S5<[u8]> = S5(&u[..]); // OK -} +trait Tr: ?Sized {} //~ ERROR relaxed bounds are not permitted in supertrait bounds + +// Test that relaxed `Sized` bounds are rejected in trait object types: + +type O1 = dyn Tr + ?Sized; //~ ERROR relaxed bounds are not permitted in trait object types +type O2 = dyn ?Sized + ?Sized + Tr; +//~^ ERROR relaxed bounds are not permitted in trait object types +//~| ERROR relaxed bounds are not permitted in trait object types + +fn main() {} + diff --git a/tests/ui/unsized/relaxed-bounds-invalid-places.stderr b/tests/ui/unsized/relaxed-bounds-invalid-places.stderr index 3287eb8d1e9..a08dc15058a 100644 --- a/tests/ui/unsized/relaxed-bounds-invalid-places.stderr +++ b/tests/ui/unsized/relaxed-bounds-invalid-places.stderr @@ -1,56 +1,77 @@ -error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared - --> $DIR/relaxed-bounds-invalid-places.rs:4:28 +error: this relaxed bound is not permitted here + --> $DIR/relaxed-bounds-invalid-places.rs:6:28 | LL | struct S1(T) 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 + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item -error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared - --> $DIR/relaxed-bounds-invalid-places.rs:7:27 +error: this relaxed bound is not permitted here + --> $DIR/relaxed-bounds-invalid-places.rs:8:27 | LL | struct S2(T) where u8: ?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 + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item -error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared +error: this relaxed bound is not permitted here --> $DIR/relaxed-bounds-invalid-places.rs:10:35 | LL | struct S3(T) where &'static 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 + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item -error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared - --> $DIR/relaxed-bounds-invalid-places.rs:15:34 +error: this relaxed bound is not permitted here + --> $DIR/relaxed-bounds-invalid-places.rs:14:34 | LL | struct S4(T) where for<'a> T: ?Trait<'a>; | ^^^^^^^^^^ | - = 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 + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item -error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared - --> $DIR/relaxed-bounds-invalid-places.rs:24:21 +error: this relaxed bound is not permitted here + --> $DIR/relaxed-bounds-invalid-places.rs:23:21 | 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 + = 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:26: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:30:20 + | +LL | type O1 = dyn Tr + ?Sized; + | ^^^^^^ + +error: relaxed bounds are not permitted in trait object types + --> $DIR/relaxed-bounds-invalid-places.rs:31:15 + | +LL | type O2 = dyn ?Sized + ?Sized + Tr; + | ^^^^^^ + +error: relaxed bounds are not permitted in trait object types + --> $DIR/relaxed-bounds-invalid-places.rs:31:24 + | +LL | type O2 = dyn ?Sized + ?Sized + Tr; + | ^^^^^^ error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/relaxed-bounds-invalid-places.rs:15:34 + --> $DIR/relaxed-bounds-invalid-places.rs:14:34 | LL | struct S4(T) where for<'a> T: ?Trait<'a>; | ^^^^^^^^^^ error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/relaxed-bounds-invalid-places.rs:19:33 + --> $DIR/relaxed-bounds-invalid-places.rs:18:33 | LL | struct S5(*const T) where T: ?Trait<'static> + ?Sized; | ^^^^^^^^^^^^^^^ ^^^^^^ @@ -59,12 +80,11 @@ LL | struct S5(*const T) where T: ?Trait<'static> + ?Sized; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/relaxed-bounds-invalid-places.rs:19:33 + --> $DIR/relaxed-bounds-invalid-places.rs:18:33 | LL | struct S5(*const T) where T: ?Trait<'static> + ?Sized; | ^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 12 previous errors -Some errors have detailed explanations: E0203, E0658. -For more information about an error, try `rustc --explain E0203`. +For more information about this error, try `rustc --explain E0203`. -- cgit 1.4.1-3-g733a5