Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -816,13 +816,21 @@ 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;
loop {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
45 changes: 45 additions & 0 deletions tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}
}
Loading