Skip to content

Commit 932462b

Browse files
committed
Don't suggest restricting bound with unstable traits on stable
On nightly, we mention the trait is unstable ``` 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) { | ++++++++++ ``` On stable, we don't suggest the trait at all ``` 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` ```
1 parent f2abf82 commit 932462b

File tree

6 files changed

+67
-15
lines changed

6 files changed

+67
-15
lines changed

compiler/rustc_middle/src/ty/diagnostics.rs

+24-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! Diagnostics related methods for `Ty`.
22
3-
use std::borrow::Cow;
43
use std::fmt::Write;
54
use std::ops::ControlFlow;
65

@@ -278,8 +277,21 @@ pub fn suggest_constraining_type_params<'a>(
278277
span_to_replace: Option<Span>,
279278
) -> bool {
280279
let mut grouped = FxHashMap::default();
280+
let mut unstable_suggestion = false;
281281
param_names_and_constraints.for_each(|(param_name, constraint, def_id)| {
282-
grouped.entry(param_name).or_insert(Vec::new()).push((constraint, def_id))
282+
let stable = match def_id {
283+
Some(def_id) => match tcx.lookup_stability(def_id) {
284+
Some(s) => s.level.is_stable(),
285+
None => true,
286+
},
287+
None => true,
288+
};
289+
if stable || tcx.sess.is_nightly_build() {
290+
grouped.entry(param_name).or_insert(Vec::new()).push((constraint, def_id));
291+
if !stable {
292+
unstable_suggestion = true;
293+
}
294+
}
283295
});
284296

285297
let mut applicability = Applicability::MachineApplicable;
@@ -464,28 +476,32 @@ pub fn suggest_constraining_type_params<'a>(
464476

465477
if suggestions.len() == 1 {
466478
let (span, suggestion, msg) = suggestions.pop().unwrap();
479+
let post = if unstable_suggestion { " but it is an `unstable` trait" } else { "" };
467480
let msg = match msg {
468481
SuggestChangingConstraintsMessage::RestrictBoundFurther => {
469-
Cow::from("consider further restricting this bound")
482+
format!("consider further restricting this bound{post}")
470483
}
471484
SuggestChangingConstraintsMessage::RestrictType { ty } => {
472-
Cow::from(format!("consider restricting type parameter `{ty}`"))
485+
format!("consider restricting type parameter `{ty}`{post}")
473486
}
474487
SuggestChangingConstraintsMessage::RestrictTypeFurther { ty } => {
475-
Cow::from(format!("consider further restricting type parameter `{ty}`"))
488+
format!("consider further restricting type parameter `{ty}`{post}")
476489
}
477490
SuggestChangingConstraintsMessage::RemoveMaybeUnsized => {
478-
Cow::from("consider removing the `?Sized` bound to make the type parameter `Sized`")
491+
format!(
492+
"consider removing the `?Sized` bound to make the type parameter `Sized`{post}"
493+
)
479494
}
480495
SuggestChangingConstraintsMessage::ReplaceMaybeUnsizedWithSized => {
481-
Cow::from("consider replacing `?Sized` with `Sized`")
496+
format!("consider replacing `?Sized` with `Sized`{post}")
482497
}
483498
};
484499

485500
err.span_suggestion_verbose(span, msg, suggestion, applicability);
486501
} else if suggestions.len() > 1 {
502+
let post = if unstable_suggestion { " but some of them are `unstable` traits" } else { "" };
487503
err.multipart_suggestion_verbose(
488-
"consider restricting type parameters",
504+
format!("consider restricting type parameters{post}"),
489505
suggestions.into_iter().map(|(span, suggestion, _)| (span, suggestion)).collect(),
490506
applicability,
491507
);

tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ LL | impl<A, B> FnOnce<A> for CachedFun<A, B>
66
|
77
note: required by a bound in `FnOnce`
88
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
9-
help: consider further restricting this bound
9+
help: consider further restricting this bound but it is an `unstable` trait
1010
|
1111
LL | A: Eq + Hash + Clone + std::marker::Tuple,
1212
| ++++++++++++++++++++
@@ -19,7 +19,7 @@ LL | impl<A, B> FnMut<A> for CachedFun<A, B>
1919
|
2020
note: required by a bound in `FnMut`
2121
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
22-
help: consider further restricting this bound
22+
help: consider further restricting this bound but it is an `unstable` trait
2323
|
2424
LL | A: Eq + Hash + Clone + std::marker::Tuple,
2525
| ++++++++++++++++++++
@@ -30,7 +30,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup
3030
LL | extern "rust-call" fn call_once(mut self, a: A) -> Self::Output {
3131
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A`
3232
|
33-
help: consider further restricting this bound
33+
help: consider further restricting this bound but it is an `unstable` trait
3434
|
3535
LL | A: Eq + Hash + Clone + std::marker::Tuple,
3636
| ++++++++++++++++++++
@@ -41,7 +41,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup
4141
LL | extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
4242
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A`
4343
|
44-
help: consider further restricting this bound
44+
help: consider further restricting this bound but it is an `unstable` trait
4545
|
4646
LL | A: Eq + Hash + Clone + std::marker::Tuple,
4747
| ++++++++++++++++++++
@@ -56,7 +56,7 @@ LL | self.call_mut(a)
5656
|
5757
note: required by a bound in `call_mut`
5858
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
59-
help: consider further restricting this bound
59+
help: consider further restricting this bound but it is an `unstable` trait
6060
|
6161
LL | A: Eq + Hash + Clone + std::marker::Tuple,
6262
| ++++++++++++++++++++

tests/ui/mir/validate/validate-unsize-cast.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ note: required by a bound in `CastTo`
1010
|
1111
LL | pub trait CastTo<U: ?Sized>: Unsize<U> {}
1212
| ^^^^^^^^^ required by this bound in `CastTo`
13-
help: consider further restricting this bound
13+
help: consider further restricting this bound but it is an `unstable` trait
1414
|
1515
LL | impl<T: ?Sized + std::marker::Unsize<U>, U: ?Sized> CastTo<U> for T {}
1616
| ++++++++++++++++++++++++
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(staged_api)]
2+
#![allow(internal_features)]
3+
#![stable(feature = "unit_test", since = "1.0.0")]
4+
5+
#[unstable(feature = "step_trait", issue = "42168")]
6+
pub trait Unstable {}
7+
8+
#[stable(feature = "unit_test", since = "1.0.0")]
9+
fn foo<T: Unstable>(_: T) {}
10+
11+
#[stable(feature = "unit_test", since = "1.0.0")]
12+
pub fn demo<T>(t: T) { //~ HELP consider restricting type parameter `T` but it is an `unstable` trait
13+
foo(t) //~ ERROR E0277
14+
}
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0277]: the trait bound `T: Unstable` is not satisfied
2+
--> $DIR/unstable-trait-suggestion.rs:13:9
3+
|
4+
LL | foo(t)
5+
| --- ^ the trait `Unstable` is not implemented for `T`
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
note: required by a bound in `foo`
10+
--> $DIR/unstable-trait-suggestion.rs:9:11
11+
|
12+
LL | fn foo<T: Unstable>(_: T) {}
13+
| ^^^^^^^^ required by this bound in `foo`
14+
help: consider restricting type parameter `T` but it is an `unstable` trait
15+
|
16+
LL | pub fn demo<T: Unstable>(t: T) {
17+
| ++++++++++
18+
19+
error: aborting due to 1 previous error
20+
21+
For more information about this error, try `rustc --explain E0277`.

tests/ui/tuple/builtin-fail.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ note: required by a bound in `assert_is_tuple`
99
|
1010
LL | fn assert_is_tuple<T: std::marker::Tuple + ?Sized>() {}
1111
| ^^^^^^^^^^^^^^^^^^ required by this bound in `assert_is_tuple`
12-
help: consider restricting type parameter `T`
12+
help: consider restricting type parameter `T` but it is an `unstable` trait
1313
|
1414
LL | fn from_param_env<T: std::marker::Tuple>() {
1515
| ++++++++++++++++++++

0 commit comments

Comments
 (0)