diff options
Diffstat (limited to 'src/test/ui/type-inference/issue-30225.rs')
-rw-r--r-- | src/test/ui/type-inference/issue-30225.rs | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/test/ui/type-inference/issue-30225.rs b/src/test/ui/type-inference/issue-30225.rs new file mode 100644 index 000000000..42315332c --- /dev/null +++ b/src/test/ui/type-inference/issue-30225.rs @@ -0,0 +1,38 @@ +// Regression test for #30225, which was an ICE that would trigger as +// a result of a poor interaction between trait result caching and +// type inference. Specifically, at that time, unification could cause +// unrelated type variables to become instantiated, if subtyping +// relationships existed. These relationships are now propagated +// through obligations and hence everything works out fine. + +trait Foo<U,V> : Sized { + fn foo(self, u: Option<U>, v: Option<V>) {} +} + +struct A; +struct B; + +impl Foo<A, B> for () {} // impl A +impl Foo<u32, u32> for u32 {} // impl B, creating ambiguity + +fn toxic() { + // cache the resolution <() as Foo<$0,$1>> = impl A + let u = None; + let v = None; + Foo::foo((), u, v); +} + +fn bomb() { + let mut u = None; // type is Option<$0> + let mut v = None; // type is Option<$1> + let mut x = None; // type is Option<$2> + + Foo::foo(x.unwrap(),u,v); // register <$2 as Foo<$0, $1>> + u = v; // mark $0 and $1 in a subtype relationship + //~^ ERROR mismatched types + x = Some(()); // set $2 = (), allowing impl selection + // to proceed for <() as Foo<$0, $1>> = impl A. + // kaboom, this *used* to trigge an ICE +} + +fn main() {} |