diff options
| -rw-r--r-- | compiler/rustc_middle/src/ty/diagnostics.rs | 32 | ||||
| -rw-r--r-- | tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr | 10 | ||||
| -rw-r--r-- | tests/ui/mir/validate/validate-unsize-cast.stderr | 2 | ||||
| -rw-r--r-- | tests/ui/trait-bounds/unstable-trait-suggestion.rs | 15 | ||||
| -rw-r--r-- | tests/ui/trait-bounds/unstable-trait-suggestion.stderr | 21 | ||||
| -rw-r--r-- | tests/ui/tuple/builtin-fail.stderr | 2 |
6 files changed, 67 insertions, 15 deletions
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index fd807882e0f..b08e1632f65 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -1,6 +1,5 @@ //! Diagnostics related methods for `Ty`. -use std::borrow::Cow; use std::fmt::Write; use std::ops::ControlFlow; @@ -278,8 +277,21 @@ pub fn suggest_constraining_type_params<'a>( span_to_replace: Option<Span>, ) -> bool { let mut grouped = FxHashMap::default(); + let mut unstable_suggestion = false; param_names_and_constraints.for_each(|(param_name, constraint, def_id)| { - grouped.entry(param_name).or_insert(Vec::new()).push((constraint, def_id)) + let stable = match def_id { + Some(def_id) => match tcx.lookup_stability(def_id) { + Some(s) => s.level.is_stable(), + None => true, + }, + None => true, + }; + if stable || tcx.sess.is_nightly_build() { + grouped.entry(param_name).or_insert(Vec::new()).push((constraint, def_id)); + if !stable { + unstable_suggestion = true; + } + } }); let mut applicability = Applicability::MachineApplicable; @@ -464,28 +476,32 @@ pub fn suggest_constraining_type_params<'a>( if suggestions.len() == 1 { let (span, suggestion, msg) = suggestions.pop().unwrap(); + let post = if unstable_suggestion { " but it is an `unstable` trait" } else { "" }; let msg = match msg { SuggestChangingConstraintsMessage::RestrictBoundFurther => { - Cow::from("consider further restricting this bound") + format!("consider further restricting this bound{post}") } SuggestChangingConstraintsMessage::RestrictType { ty } => { - Cow::from(format!("consider restricting type parameter `{ty}`")) + format!("consider restricting type parameter `{ty}`{post}") } SuggestChangingConstraintsMessage::RestrictTypeFurther { ty } => { - Cow::from(format!("consider further restricting type parameter `{ty}`")) + format!("consider further restricting type parameter `{ty}`{post}") } SuggestChangingConstraintsMessage::RemoveMaybeUnsized => { - Cow::from("consider removing the `?Sized` bound to make the type parameter `Sized`") + format!( + "consider removing the `?Sized` bound to make the type parameter `Sized`{post}" + ) } SuggestChangingConstraintsMessage::ReplaceMaybeUnsizedWithSized => { - Cow::from("consider replacing `?Sized` with `Sized`") + format!("consider replacing `?Sized` with `Sized`{post}") } }; err.span_suggestion_verbose(span, msg, suggestion, applicability); } else if suggestions.len() > 1 { + let post = if unstable_suggestion { " but some of them are `unstable` traits" } else { "" }; err.multipart_suggestion_verbose( - "consider restricting type parameters", + format!("consider restricting type parameters{post}"), suggestions.into_iter().map(|(span, suggestion, _)| (span, suggestion)).collect(), applicability, ); diff --git a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr index 206a6801065..17506dadb9f 100644 --- a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr +++ b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr @@ -6,7 +6,7 @@ LL | impl<A, B> FnOnce<A> for CachedFun<A, B> | note: required by a bound in `FnOnce` --> $SRC_DIR/core/src/ops/function.rs:LL:COL -help: consider further restricting this bound +help: consider further restricting this bound but it is an `unstable` trait | LL | A: Eq + Hash + Clone + std::marker::Tuple, | ++++++++++++++++++++ @@ -19,7 +19,7 @@ LL | impl<A, B> FnMut<A> for CachedFun<A, B> | note: required by a bound in `FnMut` --> $SRC_DIR/core/src/ops/function.rs:LL:COL -help: consider further restricting this bound +help: consider further restricting this bound but it is an `unstable` trait | LL | A: Eq + Hash + Clone + std::marker::Tuple, | ++++++++++++++++++++ @@ -30,7 +30,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup LL | extern "rust-call" fn call_once(mut self, a: A) -> Self::Output { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A` | -help: consider further restricting this bound +help: consider further restricting this bound but it is an `unstable` trait | LL | A: Eq + Hash + Clone + std::marker::Tuple, | ++++++++++++++++++++ @@ -41,7 +41,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup LL | extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A` | -help: consider further restricting this bound +help: consider further restricting this bound but it is an `unstable` trait | LL | A: Eq + Hash + Clone + std::marker::Tuple, | ++++++++++++++++++++ @@ -56,7 +56,7 @@ LL | self.call_mut(a) | note: required by a bound in `call_mut` --> $SRC_DIR/core/src/ops/function.rs:LL:COL -help: consider further restricting this bound +help: consider further restricting this bound but it is an `unstable` trait | LL | A: Eq + Hash + Clone + std::marker::Tuple, | ++++++++++++++++++++ diff --git a/tests/ui/mir/validate/validate-unsize-cast.stderr b/tests/ui/mir/validate/validate-unsize-cast.stderr index cfb47b34e98..513e1e597bf 100644 --- a/tests/ui/mir/validate/validate-unsize-cast.stderr +++ b/tests/ui/mir/validate/validate-unsize-cast.stderr @@ -10,7 +10,7 @@ note: required by a bound in `CastTo` | LL | pub trait CastTo<U: ?Sized>: Unsize<U> {} | ^^^^^^^^^ required by this bound in `CastTo` -help: consider further restricting this bound +help: consider further restricting this bound but it is an `unstable` trait | LL | impl<T: ?Sized + std::marker::Unsize<U>, U: ?Sized> CastTo<U> for T {} | ++++++++++++++++++++++++ diff --git a/tests/ui/trait-bounds/unstable-trait-suggestion.rs b/tests/ui/trait-bounds/unstable-trait-suggestion.rs new file mode 100644 index 00000000000..fff61e4a6f5 --- /dev/null +++ b/tests/ui/trait-bounds/unstable-trait-suggestion.rs @@ -0,0 +1,15 @@ +#![feature(staged_api)] +#![allow(internal_features)] +#![stable(feature = "unit_test", since = "1.0.0")] + +#[unstable(feature = "step_trait", issue = "42168")] +pub trait Unstable {} + +#[stable(feature = "unit_test", since = "1.0.0")] +fn foo<T: Unstable>(_: T) {} + +#[stable(feature = "unit_test", since = "1.0.0")] +pub fn demo<T>(t: T) { //~ HELP consider restricting type parameter `T` but it is an `unstable` trait + foo(t) //~ ERROR E0277 +} +fn main() {} diff --git a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr new file mode 100644 index 00000000000..7b5e9f8d124 --- /dev/null +++ b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `T: Unstable` is not satisfied + --> $DIR/unstable-trait-suggestion.rs:13:9 + | +LL | foo(t) + | --- ^ the trait `Unstable` is not implemented for `T` + | | + | required by a bound introduced by this call + | +note: required by a bound in `foo` + --> $DIR/unstable-trait-suggestion.rs:9:11 + | +LL | fn foo<T: Unstable>(_: T) {} + | ^^^^^^^^ required by this bound in `foo` +help: consider restricting type parameter `T` but it is an `unstable` trait + | +LL | pub fn demo<T: Unstable>(t: T) { + | ++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/tuple/builtin-fail.stderr b/tests/ui/tuple/builtin-fail.stderr index e3e29a73fdc..cc295dabb17 100644 --- a/tests/ui/tuple/builtin-fail.stderr +++ b/tests/ui/tuple/builtin-fail.stderr @@ -9,7 +9,7 @@ note: required by a bound in `assert_is_tuple` | LL | fn assert_is_tuple<T: std::marker::Tuple + ?Sized>() {} | ^^^^^^^^^^^^^^^^^^ required by this bound in `assert_is_tuple` -help: consider restricting type parameter `T` +help: consider restricting type parameter `T` but it is an `unstable` trait | LL | fn from_param_env<T: std::marker::Tuple>() { | ++++++++++++++++++++ |
