Skip to content

Commit 233fd9a

Browse files
committed
keep inductive cycles as ambig in coherence
1 parent fc8a474 commit 233fd9a

File tree

4 files changed

+54
-3
lines changed

4 files changed

+54
-3
lines changed

Diff for: compiler/rustc_next_trait_solver/src/solve/search_graph.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use std::convert::Infallible;
22
use std::marker::PhantomData;
33

4-
use rustc_type_ir::Interner;
54
use rustc_type_ir::search_graph::{self, PathKind};
65
use rustc_type_ir::solve::{CanonicalInput, Certainty, NoSolution, QueryResult};
6+
use rustc_type_ir::{Interner, TypingMode};
77

88
use super::inspect::ProofTreeBuilder;
99
use super::{FIXPOINT_STEP_LIMIT, has_no_inference_or_external_constraints};
@@ -48,7 +48,23 @@ where
4848
match kind {
4949
PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes),
5050
PathKind::Unknown => response_no_constraints(cx, input, Certainty::overflow(false)),
51-
PathKind::Inductive => Err(NoSolution),
51+
// Even though we know these cycles to be unproductive, we still return
52+
// overflow during coherence. This is both as we are not 100% confident in
53+
// the implementation yet and any incorrect errors would be unsound there.
54+
// The affected cases are also fairly artificial and not necessarily desirable
55+
// so keeping this as ambiguity is fine for now.
56+
//
57+
// See `tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs` for an
58+
// example where this would matter. We likely should change these cycles to `NoSolution`
59+
// even in coherence once this is a bit more settled.
60+
PathKind::Inductive => match input.typing_mode {
61+
TypingMode::Coherence => {
62+
response_no_constraints(cx, input, Certainty::overflow(false))
63+
}
64+
TypingMode::Analysis { .. }
65+
| TypingMode::PostBorrowckAnalysis { .. }
66+
| TypingMode::PostAnalysis => Err(NoSolution),
67+
},
5268
}
5369
}
5470

Diff for: compiler/rustc_type_ir/src/search_graph/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,10 @@ pub trait Delegate {
115115
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
116116
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
117117
pub enum PathKind {
118-
/// A path consisting of only inductive/unproductive steps.
118+
/// A path consisting of only inductive/unproductive steps. Their initial
119+
/// provisional result is `Err(NoSolution)`. We currently treat them as
120+
/// `PathKind::Unknown` during coherence until we're fully confident in
121+
/// our approach.
119122
Inductive,
120123
/// A path which is not be coinductive right now but we may want
121124
/// to change of them to be so in the future. We return an ambiguous
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// If we treat known inductive cycles as errors, this test compiles
2+
// as normalizing `Overflow::Assoc<Overflow>` fails.
3+
//
4+
// As coherence already uses the new solver on stable, this change
5+
// would require an FCP.
6+
7+
trait Trait {
8+
type Assoc<T: Trait>;
9+
}
10+
11+
struct Overflow;
12+
impl Trait for Overflow {
13+
type Assoc<T: Trait> = <T as Trait>::Assoc<Overflow>;
14+
}
15+
16+
trait Overlap<T, WfHack> {}
17+
impl<T: Trait, U: Copy> Overlap<T::Assoc<T>, U> for T {}
18+
impl<U> Overlap<u32, U> for Overflow {}
19+
//~^ ERROR conflicting implementations of trait `Overlap<<Overflow as Trait>::Assoc<Overflow>, _>` for type `Overflow`
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0119]: conflicting implementations of trait `Overlap<<Overflow as Trait>::Assoc<Overflow>, _>` for type `Overflow`
2+
--> $DIR/unproductive-in-coherence.rs:18:1
3+
|
4+
LL | impl<T: Trait, U: Copy> Overlap<T::Assoc<T>, U> for T {}
5+
| ----------------------------------------------------- first implementation here
6+
LL | impl<U> Overlap<u32, U> for Overflow {}
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Overflow`
8+
9+
error: aborting due to 1 previous error
10+
11+
For more information about this error, try `rustc --explain E0119`.

0 commit comments

Comments
 (0)