Skip to content

Commit 3620c77

Browse files
committed
fix, seems to hang though
1 parent 68f64af commit 3620c77

File tree

6 files changed

+118
-73
lines changed

6 files changed

+118
-73
lines changed

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ enum CurrentGoalKind {
4747
/// These are currently the only goals whose impl where-clauses are considered to be
4848
/// productive steps.
4949
CoinductiveTrait,
50+
/// `AliasRelate` goals are used for normalization and their inference constraints are
51+
/// necessary to guide inference for other goals. This means that even on overflow, we don't
52+
/// discard inference constraints from `AliasRelate` and return them to the caller.
53+
AliasRelate,
5054
/// Unlike other goals, `NormalizesTo` goals act like functions with the expected term
5155
/// always being fully unconstrained. This would weaken inference however, as the nested
5256
/// goals never get the inference constraints from the actual normalized-to type.
@@ -67,6 +71,7 @@ impl CurrentGoalKind {
6771
CurrentGoalKind::Misc
6872
}
6973
}
74+
ty::PredicateKind::AliasRelate(..) => CurrentGoalKind::AliasRelate,
7075
ty::PredicateKind::NormalizesTo(_) => CurrentGoalKind::NormalizesTo,
7176
_ => CurrentGoalKind::Misc,
7277
}
@@ -293,6 +298,7 @@ where
293298
// so we treat cycles involving where-clauses of not-yet coinductive
294299
// traits as ambiguous for now.
295300
CurrentGoalKind::Misc => PathKind::Unknown,
301+
CurrentGoalKind::AliasRelate => unreachable!(),
296302
},
297303
// Relating types is always unproductive. If we were to map proof trees to
298304
// corecursive functions as explained in #136824, relating types never
@@ -1276,23 +1282,30 @@ where
12761282
}
12771283
};
12781284

1279-
if let Certainty::Maybe {
1280-
cause: cause @ MaybeCause::Overflow { keep_constraints: false, .. },
1281-
opaque_types_jank,
1282-
} = certainty
1283-
{
1284-
// If we have overflow, it's probable that we're substituting a type
1285-
// into itself infinitely and any partial substitutions in the query
1286-
// response are probably not useful anyways, so just return an empty
1287-
// query response.
1288-
//
1289-
// This may prevent us from potentially useful inference, e.g.
1290-
// 2 candidates, one ambiguous and one overflow, which both
1291-
// have the same inference constraints.
1292-
//
1293-
// Changing this to retain some constraints in the future
1294-
// won't be a breaking change, so this is good enough for now.
1295-
return Ok(self.make_ambiguous_response_no_constraints(cause, opaque_types_jank));
1285+
match self.current_goal_kind {
1286+
CurrentGoalKind::AliasRelate | CurrentGoalKind::NormalizesTo => {}
1287+
CurrentGoalKind::Misc | CurrentGoalKind::CoinductiveTrait => {
1288+
if let Certainty::Maybe {
1289+
cause: cause @ MaybeCause::Overflow { keep_constraints: false, .. },
1290+
opaque_types_jank,
1291+
} = certainty
1292+
{
1293+
// If we have overflow, it's probable that we're substituting a type
1294+
// into itself infinitely and any partial substitutions in the query
1295+
// response are probably not useful anyways, so just return an empty
1296+
// query response.
1297+
//
1298+
// This may prevent us from potentially useful inference, e.g.
1299+
// 2 candidates, one ambiguous and one overflow, which both
1300+
// have the same inference constraints.
1301+
//
1302+
// Changing this to retain some constraints in the future
1303+
// won't be a breaking change, so this is good enough for now.
1304+
return Ok(
1305+
self.make_ambiguous_response_no_constraints(cause, opaque_types_jank)
1306+
);
1307+
}
1308+
}
12961309
}
12971310

12981311
let external_constraints =
@@ -1327,7 +1340,9 @@ where
13271340
// causing a coherence error in diesel, see #131969. We still bail with overflow
13281341
// when later returning from the parent AliasRelate goal.
13291342
CurrentGoalKind::NormalizesTo => {}
1330-
CurrentGoalKind::Misc | CurrentGoalKind::CoinductiveTrait => {
1343+
CurrentGoalKind::AliasRelate
1344+
| CurrentGoalKind::Misc
1345+
| CurrentGoalKind::CoinductiveTrait => {
13311346
let num_non_region_vars = canonical
13321347
.variables
13331348
.iter()

tests/ui/traits/next-solver/alias-bound-unsound.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,8 @@ impl Foo for () {
2626
fn main() {
2727
let x = String::from("hello, world");
2828
let _ = identity(<() as Foo>::copy_me(&x));
29-
//~^ ERROR overflow evaluating the requirement `String <: <() as Foo>::Item`
30-
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item well-formed`
31-
//~| ERROR overflow evaluating the requirement `&<() as Foo>::Item well-formed`
32-
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
33-
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
34-
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
35-
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
29+
//~^ ERROR type mismatch resolving `<() as Foo>::Item normalizes-to String`
30+
//~| ERROR type mismatch resolving `<() as Foo>::Item normalizes-to String`
31+
//~| ERROR mismatched types
3632
println!("{x}");
3733
}

tests/ui/traits/next-solver/alias-bound-unsound.stderr

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,52 +12,53 @@ LL | trait Foo {
1212
LL | type Item: Copy
1313
| ^^^^ this trait's associated type doesn't have the requirement `String: Copy`
1414

15-
error[E0275]: overflow evaluating the requirement `String <: <() as Foo>::Item`
15+
error[E0271]: type mismatch resolving `<() as Foo>::Item normalizes-to String`
1616
--> $DIR/alias-bound-unsound.rs:28:43
1717
|
1818
LL | let _ = identity(<() as Foo>::copy_me(&x));
19-
| ^^
20-
21-
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
22-
--> $DIR/alias-bound-unsound.rs:28:22
23-
|
24-
LL | let _ = identity(<() as Foo>::copy_me(&x));
25-
| ^^^^^^^^^^^^^^^^^^^^^^^^
26-
27-
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
28-
--> $DIR/alias-bound-unsound.rs:28:22
19+
| ^^ types differ
2920
|
30-
LL | let _ = identity(<() as Foo>::copy_me(&x));
31-
| ^^^^^^^^^^^^^^^^^^^^^^^^
21+
note: required by a bound in `Foo::Item`
22+
--> $DIR/alias-bound-unsound.rs:14:30
3223
|
33-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
24+
LL | type Item: Copy
25+
| ---- required by a bound in this associated type
26+
LL | where
27+
LL | <Self as Foo>::Item: Copy;
28+
| ^^^^ required by this bound in `Foo::Item`
3429

35-
error[E0275]: overflow evaluating the requirement `&<() as Foo>::Item well-formed`
30+
error[E0308]: mismatched types
3631
--> $DIR/alias-bound-unsound.rs:28:43
3732
|
3833
LL | let _ = identity(<() as Foo>::copy_me(&x));
39-
| ^^
40-
41-
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item well-formed`
42-
--> $DIR/alias-bound-unsound.rs:28:22
34+
| -------------------- ^^ types differ
35+
| |
36+
| arguments to this function are incorrect
4337
|
44-
LL | let _ = identity(<() as Foo>::copy_me(&x));
45-
| ^^^^^^^^^^^^^^^^^^^^^^^^
38+
= note: expected reference `&<() as Foo>::Item`
39+
found reference `&String`
40+
note: associated function defined here
41+
--> $DIR/alias-bound-unsound.rs:16:8
42+
|
43+
LL | fn copy_me(x: &Self::Item) -> Self::Item {
44+
| ^^^^^^^ --------------
4645

47-
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
46+
error[E0271]: type mismatch resolving `<() as Foo>::Item normalizes-to String`
4847
--> $DIR/alias-bound-unsound.rs:28:22
4948
|
5049
LL | let _ = identity(<() as Foo>::copy_me(&x));
51-
| ^^^^^^^^^^^^^^^^^^^^^^^^
50+
| ^^^^^^^^^^^^^^^^^^^^^^^^ types differ
5251
|
53-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
54-
55-
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
56-
--> $DIR/alias-bound-unsound.rs:28:43
52+
note: required by a bound in `Foo::Item`
53+
--> $DIR/alias-bound-unsound.rs:14:30
5754
|
58-
LL | let _ = identity(<() as Foo>::copy_me(&x));
59-
| ^^
55+
LL | type Item: Copy
56+
| ---- required by a bound in this associated type
57+
LL | where
58+
LL | <Self as Foo>::Item: Copy;
59+
| ^^^^ required by this bound in `Foo::Item`
6060

61-
error: aborting due to 8 previous errors
61+
error: aborting due to 4 previous errors
6262

63-
For more information about this error, try `rustc --explain E0275`.
63+
Some errors have detailed explanations: E0271, E0275, E0308.
64+
For more information about an error, try `rustc --explain E0271`.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//@ compile-flags: -Znext-solver
2+
//@ check-pass
3+
4+
// Regression test for trait-system-refactor-initiative#246.
5+
6+
struct MarkedStruct;
7+
pub trait MarkerTrait {}
8+
impl MarkerTrait for MarkedStruct {}
9+
10+
// Necessary indirection to get a cycle with `PathKind::Unknown`
11+
struct ChainStruct;
12+
trait ChainTrait {}
13+
impl ChainTrait for ChainStruct where MarkedStruct: MarkerTrait {}
14+
15+
pub struct FooStruct;
16+
pub trait FooTrait {
17+
type Output;
18+
}
19+
pub struct FooOut;
20+
impl FooTrait for FooStruct
21+
where
22+
ChainStruct: ChainTrait,
23+
{
24+
type Output = FooOut;
25+
}
26+
27+
pub trait Trait<T> {
28+
type Output;
29+
}
30+
31+
// prove <<FooStruct as FooTrait>::Output as Trait<K>>::Output: MarkerTrait
32+
// normalize <<FooStruct as FooTrait>::Output as Trait<K>>::Output
33+
// `<?fresh_infer as Trait<K>>::Output` remains ambiguous, so this alias is never rigid
34+
// alias-relate <FooStruct as FooTrait>::Output ?fresh_infer
35+
// does not constrain `?fresh_infer` as `keep_constraints` is `false`
36+
// normalize <FooStruct as FooTrait>::Output
37+
// result `FooOut` with overflow
38+
// prove ChainStruct: ChainTrait
39+
// prove MarkedStruct: MarkerTrait
40+
// impl trivial (ignored)
41+
// where-clause requires normalize <<FooStruct as FooTrait>::Output as Trait<K>>::Output overflow
42+
pub fn foo<K>()
43+
where
44+
FooOut: Trait<K>,
45+
<<FooStruct as FooTrait>::Output as Trait<K>>::Output: MarkerTrait,
46+
{
47+
}
48+
49+
fn main() {}

tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.next.stderr

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ note: required by a bound in `transmute`
1010
LL | fn transmute<L: Trait<R>, R>(r: L) -> <L::Proof as Trait<R>>::Proof { r }
1111
| ^^^^^^^^ required by this bound in `transmute`
1212

13-
error[E0275]: overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == _`
14-
--> $DIR/item-bound-via-impl-where-clause.rs:31:21
15-
|
16-
LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18-
1913
error[E0275]: overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == String`
2014
--> $DIR/item-bound-via-impl-where-clause.rs:31:21
2115
|
@@ -36,14 +30,6 @@ error[E0275]: overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::
3630
LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
3731
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3832

39-
error[E0275]: overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == _`
40-
--> $DIR/item-bound-via-impl-where-clause.rs:31:21
41-
|
42-
LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
43-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44-
|
45-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
46-
47-
error: aborting due to 6 previous errors
33+
error: aborting due to 4 previous errors
4834

4935
For more information about this error, try `rustc --explain E0275`.

tests/ui/traits/next-solver/cycles/coinduction/item-bound-via-impl-where-clause.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,8 @@ fn transmute<L: Trait<R>, R>(r: L) -> <L::Proof as Trait<R>>::Proof { r }
3030
fn main() {
3131
let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
3232
//~^ ERROR overflow evaluating the requirement `Vec<u8>: Trait<String>`
33-
//[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == _`
3433
//[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == String`
3534
//[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof: Sized`
3635
//[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof well-formed`
37-
//[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == _`
3836
println!("{}", s); // ABC
3937
}

0 commit comments

Comments
 (0)