Skip to content

Commit 4fde241

Browse files
committed
elaborate obligations in coherence
1 parent cf77474 commit 4fde241

13 files changed

+117
-8
lines changed

compiler/rustc_trait_selection/src/traits/coherence.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,12 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
358358
) -> IntersectionHasImpossibleObligations<'tcx> {
359359
let infcx = selcx.infcx;
360360

361+
// Elaborate obligations in case the current obligation is unknowable,
362+
// but its super trait bound is not. See #124532 for more details.
363+
let obligations = util::elaborate(infcx.tcx, obligations.iter().cloned());
361364
if infcx.next_trait_solver() {
362365
let ocx = ObligationCtxt::new(infcx);
363-
ocx.register_obligations(obligations.iter().cloned());
366+
ocx.register_obligations(obligations);
364367
let errors_and_ambiguities = ocx.select_all_or_error();
365368
// We only care about the obligations that are *definitely* true errors.
366369
// Ambiguities do not prove the disjointness of two impls.
@@ -387,7 +390,7 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
387390
for obligation in obligations {
388391
// We use `evaluate_root_obligation` to correctly track intercrate
389392
// ambiguity clauses.
390-
let evaluation_result = selcx.evaluate_root_obligation(obligation);
393+
let evaluation_result = selcx.evaluate_root_obligation(&obligation);
391394

392395
match evaluation_result {
393396
Ok(result) => {

src/tools/tidy/src/issues.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4061,7 +4061,6 @@ ui/traits/issue-6128.rs
40614061
ui/traits/issue-6334.rs
40624062
ui/traits/issue-65284-suggest-generic-trait-bound.rs
40634063
ui/traits/issue-65673.rs
4064-
ui/traits/issue-66768.rs
40654064
ui/traits/issue-68295.rs
40664065
ui/traits/issue-7013.rs
40674066
ui/traits/issue-70944.rs

tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ LL | | for<'a> <T as WithAssoc<'a>>::Assoc: WhereBound,
1111
LL | impl<T> Trait for Box<T> {}
1212
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
1313
|
14-
= note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>`
1514
= note: downstream crates may implement trait `WhereBound` for type `<std::boxed::Box<_> as WithAssoc<'a>>::Assoc`
15+
= note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>`
1616

1717
error: aborting due to 1 previous error
1818

tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ LL | | for<'a> Box<<T as WithAssoc<'a>>::Assoc>: WhereBound,
1111
LL | impl<T> Trait for Box<T> {}
1212
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
1313
|
14-
= note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>`
1514
= note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box<<std::boxed::Box<_> as WithAssoc<'a>>::Assoc>`
15+
= note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>`
1616

1717
error: aborting due to 1 previous error
1818

tests/ui/coherence/normalize-for-errors.current.stderr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Ite
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, _)`
99
|
1010
= note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
11+
= note: upstream crates may add a new impl of trait `std::clone::Clone` for type `(MyType,)` in future versions
1112

1213
error: aborting due to 1 previous error
1314

tests/ui/coherence/normalize-for-errors.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
1818
//~^ ERROR conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>,
1919
//~| NOTE conflicting implementation for `(Box<(MyType,)>,
2020
//~| NOTE upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
21+
//[current]~| NOTE upstream crates may add a new impl of trait `std::clone::Clone` for type `(MyType,)` in future versions
2122

2223
fn main() {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Added in #124532. While `(): Super` is knowable, `(): Sub<?t>` is not.
2+
//
3+
// We therefore elaborate super trait bounds in the implicit negative
4+
// overlap check.
5+
6+
//@ revisions: current next
7+
//@ ignore-compare-mode-next-solver (explicit revisions)
8+
//@[next] compile-flags: -Znext-solver
9+
//@ check-pass
10+
11+
trait Super {}
12+
trait Sub<T>: Super {}
13+
14+
trait Overlap<T> {}
15+
impl<T, U: Sub<T>> Overlap<T> for U {}
16+
impl<T> Overlap<T> for () {}
17+
18+
fn main() {}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// A regression test for pyella-0.1.5 which broke when
2+
// enabling the new solver in coherence.
3+
//
4+
// `Tensor: TensorValue` is knowable while `Tensor: TensorOp<?t2>`
5+
// may be implemented downstream. We previously didn't check the
6+
// super trait bound in coherence, causing these impls to overlap.
7+
//
8+
// However, we did fail to normalize `<Tensor as TensorValue::Unmasked`
9+
// which caused the old solver to emit a `Tensor: TensorValue` goal in
10+
// `fn normalize_to_error` which then failed, causing this test to pass.
11+
12+
//@ revisions: current next
13+
//@ ignore-compare-mode-next-solver (explicit revisions)
14+
//@[next] compile-flags: -Znext-solver
15+
//@ check-pass
16+
17+
pub trait TensorValue {
18+
type Unmasked;
19+
}
20+
21+
trait TensorCompare<T> {}
22+
pub trait TensorOp<T>: TensorValue {}
23+
24+
pub struct Tensor;
25+
impl<T2> TensorCompare<T2> for Tensor {}
26+
impl<T1, T2> TensorCompare<T2> for T1
27+
where
28+
T1: TensorOp<T2>,
29+
T1::Unmasked: Sized,
30+
{}
31+
32+
33+
fn main() {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()`
2+
--> $DIR/super-trait-knowable-nested.rs:19:1
3+
|
4+
LL | impl<T, U: Bound<T>> Overlap<T> for U {}
5+
| ------------------------------------- first implementation here
6+
LL | impl<T> Overlap<T> for () {}
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
8+
|
9+
= note: downstream crates may implement trait `Bound<_>` for type `()`
10+
11+
error: aborting due to 1 previous error
12+
13+
For more information about this error, try `rustc --explain E0119`.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()`
2+
--> $DIR/super-trait-knowable-nested.rs:19:1
3+
|
4+
LL | impl<T, U: Bound<T>> Overlap<T> for U {}
5+
| ------------------------------------- first implementation here
6+
LL | impl<T> Overlap<T> for () {}
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
8+
|
9+
= note: downstream crates may implement trait `Bound<_>` for type `()`
10+
11+
error: aborting due to 1 previous error
12+
13+
For more information about this error, try `rustc --explain E0119`.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Unlike in `super-trait-knowable-1.rs`, the knowable
2+
// super trait bound is in a nested goal and we currently
3+
// only elaborate in the root. This can, and should, be#
4+
// changed in the future.
5+
6+
//@ revisions: current next
7+
//@ ignore-compare-mode-next-solver (explicit revisions)
8+
//@[next] compile-flags: -Znext-solver
9+
10+
trait Super {}
11+
trait Sub<T>: Super {}
12+
13+
trait Bound<T> {}
14+
15+
impl<T: Sub<T>, U> Bound<U> for T {}
16+
17+
trait Overlap<T> {}
18+
impl<T, U: Bound<T>> Overlap<T> for U {}
19+
impl<T> Overlap<T> for () {}
20+
//~^ ERROR conflicting implementations of trait `Overlap<_>` for type `()`
21+
22+
fn main() {}

tests/ui/issues/issue-48728.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
// Regression test for #48728, an ICE that occurred computing
22
// coherence "help" information.
33

4-
#[derive(Clone)] //~ ERROR conflicting implementations of trait `Clone`
4+
//@ revisions: current next
5+
//@ ignore-compare-mode-next-solver (explicit revisions)
6+
//@[next] compile-flags: -Znext-solver
7+
//@ check-pass
8+
9+
#[derive(Clone)]
510
struct Node<T: ?Sized>(Box<T>);
611

712
impl<T: Clone + ?Sized> Clone for Node<[T]> {

tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>`
1+
error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>>`
22
--> $DIR/coherence-fulfill-overflow.rs:12:1
33
|
44
LL | impl<T: ?Sized + TwoW> Trait for W<T> {}
55
| ------------------------------------- first implementation here
66
LL | impl<T: ?Sized + TwoW> Trait for T {}
7-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>`
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>>`
88
|
9+
= note: overflow evaluating the requirement `W<W<W<W<W<_>>>>>: TwoW`
910
= note: overflow evaluating the requirement `W<W<W<W<_>>>>: TwoW`
1011
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`coherence_fulfill_overflow`)
1112

0 commit comments

Comments
 (0)