mirror of
https://github.com/rust-lang/rust.git
synced 2026-06-02 06:28:20 +03:00
Rollup merge of #156676 - qaijuang:diagnostics-do-not-recommend-span, r=chenyukang
Preserve spans when hiding do_not_recommend impls Fixes rust-lang/rust#156475 by restoring the root span only when the current refined span has wandered outside the parent obligation.
This commit is contained in:
@@ -816,6 +816,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
pub(super) fn apply_do_not_recommend(
|
||||
&self,
|
||||
obligation: &mut PredicateObligation<'tcx>,
|
||||
root_obligation: &PredicateObligation<'tcx>,
|
||||
) -> bool {
|
||||
let mut base_cause = obligation.cause.code().clone();
|
||||
let mut applied_do_not_recommend = false;
|
||||
@@ -823,6 +824,13 @@ pub(super) fn apply_do_not_recommend(
|
||||
if let ObligationCauseCode::ImplDerived(ref c) = base_cause {
|
||||
if self.tcx.do_not_recommend_impl(c.impl_or_alias_def_id) {
|
||||
let code = (*c.derived.parent_code).clone();
|
||||
// Keep more precise spans that still point within the parent obligation,
|
||||
// but do not let hidden impl details move the span outside of it.
|
||||
if code == *root_obligation.cause.code()
|
||||
&& !root_obligation.cause.span.contains(obligation.cause.span)
|
||||
{
|
||||
obligation.cause.span = root_obligation.cause.span;
|
||||
}
|
||||
obligation.cause.map_code(|_| code);
|
||||
obligation.predicate = c.derived.parent_trait_pred.upcast(self.tcx);
|
||||
applied_do_not_recommend = true;
|
||||
|
||||
@@ -298,7 +298,7 @@ fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuara
|
||||
error.code,
|
||||
FulfillmentErrorCode::Select(crate::traits::SelectionError::Unimplemented)
|
||||
| FulfillmentErrorCode::Project(_)
|
||||
) && self.apply_do_not_recommend(&mut error.obligation)
|
||||
) && self.apply_do_not_recommend(&mut error.obligation, &error.root_obligation)
|
||||
{
|
||||
error.code = FulfillmentErrorCode::Select(SelectionError::Unimplemented);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,26 @@ LL | impl AsExpression<Text> for &'_ str {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= help: for that trait implementation, expected `Text`, found `Integer`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0277]: the trait bound `X: A` is not satisfied
|
||||
--> $DIR/as_expression.rs:60:15
|
||||
|
|
||||
LL | X.start().foo().finish();
|
||||
| ^^^ unsatisfied trait bound
|
||||
|
|
||||
help: the trait `A` is not implemented for `X`
|
||||
--> $DIR/as_expression.rs:70:1
|
||||
|
|
||||
LL | struct X;
|
||||
| ^^^^^^^^
|
||||
note: required by a bound in `Ext::foo`
|
||||
--> $DIR/as_expression.rs:79:23
|
||||
|
|
||||
LL | fn foo(self) -> Self
|
||||
| --- required by a bound in this associated function
|
||||
LL | where
|
||||
LL | Self: Sized + A;
|
||||
| ^ required by this bound in `Ext::foo`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
||||
@@ -22,6 +22,26 @@ LL | where
|
||||
LL | T: AsExpression<Self::SqlType>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::check`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0277]: the trait bound `X: A` is not satisfied
|
||||
--> $DIR/as_expression.rs:60:15
|
||||
|
|
||||
LL | X.start().foo().finish();
|
||||
| ^^^ unsatisfied trait bound
|
||||
|
|
||||
help: the trait `A` is not implemented for `X`
|
||||
--> $DIR/as_expression.rs:70:1
|
||||
|
|
||||
LL | struct X;
|
||||
| ^^^^^^^^
|
||||
note: required by a bound in `Ext::foo`
|
||||
--> $DIR/as_expression.rs:79:23
|
||||
|
|
||||
LL | fn foo(self) -> Self
|
||||
| --- required by a bound in this associated function
|
||||
LL | where
|
||||
LL | Self: Sized + A;
|
||||
| ^ required by this bound in `Ext::foo`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
||||
@@ -55,4 +55,49 @@ impl<T> Foo for T where T: Expression {}
|
||||
fn main() {
|
||||
SelectInt.check("bar");
|
||||
//~^ ERROR the trait bound `&str: AsExpression<Integer>` is not satisfied
|
||||
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/156475.
|
||||
X.start().foo().finish();
|
||||
//~^ ERROR the trait bound `X: A` is not satisfied
|
||||
}
|
||||
|
||||
trait A {}
|
||||
trait B {}
|
||||
|
||||
#[diagnostic::do_not_recommend]
|
||||
impl<T: B> A for T {}
|
||||
|
||||
struct X;
|
||||
|
||||
trait Start {
|
||||
fn start(self) -> Self;
|
||||
}
|
||||
|
||||
trait Ext {
|
||||
fn foo(self) -> Self
|
||||
where
|
||||
Self: Sized + A;
|
||||
}
|
||||
|
||||
trait Finish {
|
||||
fn finish(self);
|
||||
}
|
||||
|
||||
impl<T> Start for T {
|
||||
fn start(self) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Ext for T {
|
||||
fn foo(self) -> Self
|
||||
where
|
||||
Self: Sized + A,
|
||||
{
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Finish for T {
|
||||
fn finish(self) {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user