Skip to content

Commit 57f7526

Browse files
committed
fix(traits): clarify conditional impl diagnostics
1 parent 3d8b14e commit 57f7526

5 files changed

Lines changed: 54 additions & 6 deletions

File tree

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2332,7 +2332,55 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
23322332
(" implemented for fn pointer `", ", cast using `as`")
23332333
}
23342334
(ty::FnPtr(..), _) => (" implemented for fn pointer `", ""),
2335-
_ => (" implemented for `", ""),
2335+
_ => {
2336+
let mut has_failing_obligations = false;
2337+
if !self.tcx.predicates_of(def_id).predicates.is_empty() {
2338+
has_failing_obligations = self.probe(|_| {
2339+
let ocx = ObligationCtxt::new(self);
2340+
self.enter_forall(trait_pred, |obligation_trait_ref| {
2341+
let impl_args = self.fresh_args_for_item(DUMMY_SP, def_id);
2342+
let impl_trait_ref = ocx.normalize(
2343+
&ObligationCause::dummy(),
2344+
param_env,
2345+
ty::EarlyBinder::bind(self.tcx, cand)
2346+
.instantiate(self.tcx, impl_args),
2347+
);
2348+
if ocx
2349+
.eq(
2350+
&ObligationCause::dummy(),
2351+
param_env,
2352+
obligation_trait_ref.trait_ref,
2353+
impl_trait_ref,
2354+
)
2355+
.is_err()
2356+
{
2357+
return false;
2358+
}
2359+
ocx.register_obligations(
2360+
self.tcx
2361+
.predicates_of(def_id)
2362+
.instantiate(self.tcx, impl_args)
2363+
.into_iter()
2364+
.map(|(clause, _)| {
2365+
Obligation::new(
2366+
self.tcx,
2367+
ObligationCause::dummy(),
2368+
param_env,
2369+
clause.skip_norm_wip(),
2370+
)
2371+
}),
2372+
);
2373+
!ocx.try_evaluate_obligations().is_empty()
2374+
})
2375+
});
2376+
}
2377+
2378+
if has_failing_obligations {
2379+
(" conditionally implemented for `", "")
2380+
} else {
2381+
(" implemented for `", "")
2382+
}
2383+
}
23362384
};
23372385
let trait_ = self.tcx.short_string(cand.print_trait_sugared(), err.long_ty_path());
23382386
let self_ty = self.tcx.short_string(cand.self_ty(), err.long_ty_path());

tests/ui/traits/copy-bounds-impl-type-params.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
8080
LL | let a = t as Box<dyn Gettable<String>>;
8181
| ^ the trait `Copy` is not implemented for `String`
8282
|
83-
help: the trait `Gettable<T>` is implemented for `S<T>`
83+
help: the trait `Gettable<T>` is conditionally implemented for `S<T>`
8484
--> $DIR/copy-bounds-impl-type-params.rs:14:1
8585
|
8686
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
@@ -100,7 +100,7 @@ error[E0277]: the trait bound `Foo: Copy` is not satisfied
100100
LL | let a: Box<dyn Gettable<Foo>> = t;
101101
| ^ the trait `Copy` is not implemented for `Foo`
102102
|
103-
help: the trait `Gettable<T>` is implemented for `S<T>`
103+
help: the trait `Gettable<T>` is conditionally implemented for `S<T>`
104104
--> $DIR/copy-bounds-impl-type-params.rs:14:1
105105
|
106106
LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}

tests/ui/traits/error_reporting/conditionally-implemented-trait-158423.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ help: the trait `Foo<'_>` is not implemented for `Test`
1111
|
1212
LL | struct Test(i32, i64);
1313
| ^^^^^^^^^^^
14-
help: the trait `Foo<'_>` is implemented for `Test`
14+
help: the trait `Foo<'_>` is conditionally implemented for `Test`
1515
--> $DIR/conditionally-implemented-trait-158423.rs:20:1
1616
|
1717
LL | impl<'a> Foo<'a> for Test where i32: Foo<'a, Assoc = i32>, i64: Foo<'a, Assoc = i64> {

tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ help: the trait `Trait<_, _, _>` is not implemented for `A<X>`
99
|
1010
LL | struct A<T>(*const T);
1111
| ^^^^^^^^^^^
12-
help: the trait `Trait<U, V, D>` is implemented for `A<T>`
12+
help: the trait `Trait<U, V, D>` is conditionally implemented for `A<T>`
1313
--> $DIR/incompleteness-unstable-result.rs:34:1
1414
|
1515
LL | / impl<T, U, V, D> Trait<U, V, D> for A<T>

tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ help: the trait `Trait<_, _, _>` is not implemented for `A<X>`
99
|
1010
LL | struct A<T>(*const T);
1111
| ^^^^^^^^^^^
12-
help: the trait `Trait<U, V, D>` is implemented for `A<T>`
12+
help: the trait `Trait<U, V, D>` is conditionally implemented for `A<T>`
1313
--> $DIR/incompleteness-unstable-result.rs:34:1
1414
|
1515
LL | / impl<T, U, V, D> Trait<U, V, D> for A<T>

0 commit comments

Comments
 (0)