Skip to content

Commit

Permalink
Rollup merge of rust-lang#125717 - weiznich:move/do_not_recommend_to_…
Browse files Browse the repository at this point in the history
…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 rust-lang#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>
-->
  • Loading branch information
compiler-errors committed Jun 4, 2024
2 parents 5019bb6 + f9adc1e commit 46a0339
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand All @@ -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() {
Expand All @@ -1021,7 +1017,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
}

trait_predicate
applied_do_not_recommend
}

fn emit_specialized_closure_kind_error(
Expand Down Expand Up @@ -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(),
Expand Down
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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`.
27 changes: 27 additions & 0 deletions tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs
Original file line number Diff line number Diff line change
@@ -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]
}

0 comments on commit 46a0339

Please sign in to comment.