mirror of https://github.com/rust-lang/rust.git
Refactor `#[diagnostic::do_not_recommend]` support
This commit refactors the `#[do_not_recommend]` support in the old parser to also apply to projection errors and not only to selection errors. This allows the attribute to be used more widely.
This commit is contained in:
parent
751691271d
commit
f9adc1ee9d
|
@ -414,7 +414,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
|
||||
let trait_predicate = bound_predicate.rebind(trait_predicate);
|
||||
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
|
||||
let trait_predicate = self.apply_do_not_recommend(trait_predicate, &mut obligation);
|
||||
|
||||
// Let's use the root obligation as the main message, when we care about the
|
||||
// most general case ("X doesn't implement Pattern<'_>") over the case that
|
||||
|
@ -996,12 +995,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
err.emit()
|
||||
}
|
||||
|
||||
fn apply_do_not_recommend(
|
||||
&self,
|
||||
mut trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
|
||||
obligation: &'_ mut PredicateObligation<'tcx>,
|
||||
) -> ty::Binder<'tcx, ty::TraitPredicate<'tcx>> {
|
||||
fn apply_do_not_recommend(&self, obligation: &mut PredicateObligation<'tcx>) -> bool {
|
||||
let mut base_cause = obligation.cause.code().clone();
|
||||
let mut applied_do_not_recommend = false;
|
||||
loop {
|
||||
if let ObligationCauseCode::ImplDerived(ref c) = base_cause {
|
||||
if self.tcx.has_attrs_with_path(
|
||||
|
@ -1011,7 +1007,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
let code = (*c.derived.parent_code).clone();
|
||||
obligation.cause.map_code(|_| code);
|
||||
obligation.predicate = c.derived.parent_trait_pred.upcast(self.tcx);
|
||||
trait_predicate = c.derived.parent_trait_pred.clone();
|
||||
applied_do_not_recommend = true;
|
||||
}
|
||||
}
|
||||
if let Some((parent_cause, _parent_pred)) = base_cause.parent() {
|
||||
|
@ -1021,7 +1017,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
trait_predicate
|
||||
applied_do_not_recommend
|
||||
}
|
||||
|
||||
fn emit_specialized_closure_kind_error(
|
||||
|
@ -1521,6 +1517,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed {
|
||||
let mut error = FulfillmentError {
|
||||
obligation: error.obligation.clone(),
|
||||
code: error.code.clone(),
|
||||
root_obligation: error.root_obligation.clone(),
|
||||
};
|
||||
if matches!(
|
||||
error.code,
|
||||
FulfillmentErrorCode::Select(crate::traits::SelectionError::Unimplemented)
|
||||
| FulfillmentErrorCode::Project(_)
|
||||
) && self.apply_do_not_recommend(&mut error.obligation)
|
||||
{
|
||||
error.code = FulfillmentErrorCode::Select(SelectionError::Unimplemented);
|
||||
}
|
||||
|
||||
match error.code {
|
||||
FulfillmentErrorCode::Select(ref selection_error) => self.report_selection_error(
|
||||
error.obligation.clone(),
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
error[E0277]: Very important message!
|
||||
--> $DIR/type_mismatch.rs:25:14
|
||||
|
|
||||
LL | verify::<u8>();
|
||||
| ^^ the trait `TheImportantOne` is not implemented for `u8`
|
||||
|
|
||||
note: required by a bound in `verify`
|
||||
--> $DIR/type_mismatch.rs:22:14
|
||||
|
|
||||
LL | fn verify<T: TheImportantOne>() {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `verify`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -0,0 +1,15 @@
|
|||
error[E0277]: Very important message!
|
||||
--> $DIR/type_mismatch.rs:25:14
|
||||
|
|
||||
LL | verify::<u8>();
|
||||
| ^^ the trait `TheImportantOne` is not implemented for `u8`
|
||||
|
|
||||
note: required by a bound in `verify`
|
||||
--> $DIR/type_mismatch.rs:22:14
|
||||
|
|
||||
LL | fn verify<T: TheImportantOne>() {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `verify`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -0,0 +1,27 @@
|
|||
//@ revisions: current next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
#![feature(do_not_recommend)]
|
||||
|
||||
#[diagnostic::on_unimplemented(message = "Very important message!")]
|
||||
trait TheImportantOne {}
|
||||
|
||||
trait ImplementationDetail {
|
||||
type Restriction;
|
||||
}
|
||||
|
||||
#[diagnostic::do_not_recommend]
|
||||
impl<T: ImplementationDetail<Restriction = ()>> TheImportantOne for T {}
|
||||
|
||||
// Comment out this `impl` to show the expected error message.
|
||||
impl ImplementationDetail for u8 {
|
||||
type Restriction = u8;
|
||||
}
|
||||
|
||||
fn verify<T: TheImportantOne>() {}
|
||||
|
||||
pub fn main() {
|
||||
verify::<u8>();
|
||||
//~^ERROR: Very important message! [E0277]
|
||||
}
|
Loading…
Reference in New Issue