Rollup merge of #125717 - weiznich:move/do_not_recommend_to_diganostic_namespace, r=compiler-errors

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.

Part of #51992

r? `@compiler-errors`

<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.

This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using

    r​? <reviewer name>
-->
This commit is contained in:
Michael Goulet 2024-06-04 08:52:12 -04:00 committed by GitHub
commit 46a033958a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 75 additions and 8 deletions

View file

@ -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(),