mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
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:
commit
46a033958a
@ -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
Block a user