Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/tests/regression/new_solver.rs')
-rw-r--r--crates/hir-ty/src/tests/regression/new_solver.rs283
1 files changed, 279 insertions, 4 deletions
diff --git a/crates/hir-ty/src/tests/regression/new_solver.rs b/crates/hir-ty/src/tests/regression/new_solver.rs
index ead79a8f5b..5c1f85cb2a 100644
--- a/crates/hir-ty/src/tests/regression/new_solver.rs
+++ b/crates/hir-ty/src/tests/regression/new_solver.rs
@@ -1,6 +1,6 @@
use expect_test::expect;
-use crate::tests::{check_infer, check_no_mismatches};
+use crate::tests::{check_infer, check_no_mismatches, check_types};
#[test]
fn regression_20365() {
@@ -84,7 +84,7 @@ fn test() -> i32 {
307..359 'core::...n Foo)': DynMetadata<dyn Foo + '?>
327..328 '0': usize
327..340 '0 as *const F': *const F
- 327..358 '0 as *...yn Foo': *const (dyn Foo + '?)
+ 327..358 '0 as *...yn Foo': *const (dyn Foo + 'static)
370..371 'f': F
374..378 'F {}': F
388..395 'fat_ptr': *const (dyn Foo + '?)
@@ -180,7 +180,7 @@ impl<'a> IntoIterator for &'a Grid {
"#,
expect![[r#"
150..154 'self': &'a Grid
- 174..181 '{ }': impl Iterator<Item = &'a ()>
+ 174..181 '{ }': ()
"#]],
);
}
@@ -414,7 +414,282 @@ fn foo() {
244..246 '_x': {unknown}
249..257 'to_bytes': fn to_bytes() -> [u8; _]
249..259 'to_bytes()': [u8; _]
- 249..268 'to_byt..._vec()': Vec<<[u8; _] as Foo>::Item>
+ 249..268 'to_byt..._vec()': {unknown}
+ "#]],
+ );
+}
+
+#[test]
+fn regression_19637() {
+ check_no_mismatches(
+ r#"
+//- minicore: coerce_unsized
+pub trait Any {}
+
+impl<T: 'static> Any for T {}
+
+pub trait Trait: Any {
+ type F;
+}
+
+pub struct TT {}
+
+impl Trait for TT {
+ type F = f32;
+}
+
+pub fn coercion(x: &mut dyn Any) -> &mut dyn Any {
+ x
+}
+
+fn main() {
+ let mut t = TT {};
+ let tt = &mut t as &mut dyn Trait<F = f32>;
+ let st = coercion(tt);
+}
+ "#,
+ );
+}
+
+#[test]
+fn double_into_iter() {
+ check_types(
+ r#"
+//- minicore: iterator
+
+fn intoiter_issue<A, B>(foo: A)
+where
+ A: IntoIterator<Item = B>,
+ B: IntoIterator<Item = usize>,
+{
+ for x in foo {
+ // ^ B
+ for m in x {
+ // ^ usize
+ }
+ }
+}
+"#,
+ );
+}
+
+#[test]
+fn regression_16282() {
+ check_infer(
+ r#"
+//- minicore: coerce_unsized, dispatch_from_dyn
+trait MapLookup<Q> {
+ type MapValue;
+}
+
+impl<K> MapLookup<K> for K {
+ type MapValue = K;
+}
+
+trait Map: MapLookup<<Self as Map>::Key> {
+ type Key;
+}
+
+impl<K> Map for K {
+ type Key = K;
+}
+
+
+fn main() {
+ let _ = &()
+ as &dyn Map<Key=u32,MapValue=u32>;
+}
+"#,
+ expect![[r#"
+ 210..272 '{ ...32>; }': ()
+ 220..221 '_': &'? (dyn Map<MapValue = u32, Key = u32> + '?)
+ 224..227 '&()': &'? ()
+ 224..269 '&() ...e=u32>': &'? (dyn Map<MapValue = u32, Key = u32> + 'static)
+ 225..227 '()': ()
+ "#]],
+ );
+}
+
+#[test]
+fn regression_18692() {
+ check_no_mismatches(
+ r#"
+//- minicore: coerce_unsized, dispatch_from_dyn, send
+trait Trait: Send {}
+
+fn f(_: *const (dyn Trait + Send)) {}
+fn g(it: *const (dyn Trait)) {
+ f(it);
+}
+"#,
+ );
+}
+
+#[test]
+fn regression_20951() {
+ check_infer(
+ r#"
+//- minicore: async_fn
+trait DoesSomething {
+ fn do_something(&self) -> impl Future<Output = usize>;
+}
+
+impl<F> DoesSomething for F
+where
+ F: AsyncFn() -> usize,
+{
+ fn do_something(&self) -> impl Future<Output = usize> {
+ self()
+ }
+}
+"#,
+ expect![[r#"
+ 43..47 'self': &'? Self
+ 168..172 'self': &'? F
+ 205..227 '{ ... }': <F as AsyncFnMut<()>>::CallRefFuture<'<erased>>
+ 215..219 'self': &'? F
+ 215..221 'self()': <F as AsyncFnMut<()>>::CallRefFuture<'<erased>>
+ "#]],
+ );
+}
+
+#[test]
+fn regression_19957() {
+ // This test documents issue #19957: async-trait patterns incorrectly produce
+ // type mismatches between Pin<Box<dyn Future>> and Pin<Box<impl Future>>.
+ check_no_mismatches(
+ r#"
+//- minicore: future, pin, result, error, send, coerce_unsized, dispatch_from_dyn
+use core::{future::Future, pin::Pin};
+
+#[lang = "owned_box"]
+pub struct Box<T: ?Sized> {
+ inner: *mut T,
+}
+
+impl<T> Box<T> {
+ fn pin(value: T) -> Pin<Box<T>> {
+ // Implementation details don't matter here for type checking
+ loop {}
+ }
+}
+
+impl<T: ?Sized + core::marker::Unsize<U>, U: ?Sized> core::ops::CoerceUnsized<Box<U>> for Box<T> {}
+
+impl<T: ?Sized + core::ops::DispatchFromDyn<U>, U: ?Sized> core::ops::DispatchFromDyn<Box<U>> for Box<T> {}
+
+pub struct ExampleData {
+ pub id: i32,
+}
+
+// Simulates what #[async_trait] expands to
+pub trait SimpleModel {
+ fn save<'life0, 'async_trait>(
+ &'life0 self,
+ ) -> Pin<Box<dyn Future<Output = i32> + Send + 'async_trait>>
+ where
+ 'life0: 'async_trait,
+ Self: 'async_trait;
+}
+
+impl SimpleModel for ExampleData {
+ fn save<'life0, 'async_trait>(
+ &'life0 self,
+ ) -> Pin<Box<dyn Future<Output = i32> + Send + 'async_trait>>
+ where
+ 'life0: 'async_trait,
+ Self: 'async_trait,
+ {
+ // Body creates Pin<Box<impl Future>>, which should coerce to Pin<Box<dyn Future>>
+ Box::pin(async move { self.id })
+ }
+}
+"#,
+ )
+}
+
+#[test]
+fn regression_20975() {
+ check_infer(
+ r#"
+//- minicore: future, iterators, range
+use core::future::Future;
+
+struct Foo<T>(T);
+
+trait X {}
+
+impl X for i32 {}
+impl X for i64 {}
+
+impl<T: X> Iterator for Foo<T> {
+ type Item = T;
+ fn next(&mut self) -> Option<Self::Item> {
+ self.next_spec()
+ }
+}
+
+trait Bar {
+ type Item;
+
+ fn next_spec(&mut self) -> Option<Self::Item>;
+}
+
+impl<T: X> Bar for Foo<T> {
+ type Item = T;
+
+ fn next_spec(&mut self) -> Option<Self::Item> {
+ None
+ }
+}
+
+struct JoinAll<F>
+where
+ F: Future,
+{
+ f: F,
+}
+
+fn join_all<I>(iter: I) -> JoinAll<<I as IntoIterator>::Item>
+where
+ I: IntoIterator,
+ <I as IntoIterator>::Item: Future,
+{
+ loop {}
+}
+
+fn main() {
+ let x = Foo(42).filter_map(|_| Some(async {}));
+ join_all(x);
+}
+"#,
+ expect![[r#"
+ 164..168 'self': &'? mut Foo<T>
+ 192..224 '{ ... }': Option<T>
+ 202..206 'self': &'? mut Foo<T>
+ 202..218 'self.n...spec()': Option<T>
+ 278..282 'self': &'? mut Self
+ 380..384 'self': &'? mut Foo<T>
+ 408..428 '{ ... }': Option<T>
+ 418..422 'None': Option<T>
+ 501..505 'iter': I
+ 614..629 '{ loop {} }': JoinAll<impl Future>
+ 620..627 'loop {}': !
+ 625..627 '{}': ()
+ 641..713 '{ ...(x); }': ()
+ 651..652 'x': FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>
+ 655..658 'Foo': fn Foo<i32>(i32) -> Foo<i32>
+ 655..662 'Foo(42)': Foo<i32>
+ 655..693 'Foo(42...c {}))': FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>
+ 659..661 '42': i32
+ 674..692 '|_| So...nc {})': impl FnMut(i32) -> Option<impl Future<Output = ()>>
+ 675..676 '_': i32
+ 678..682 'Some': fn Some<impl Future<Output = ()>>(impl Future<Output = ()>) -> Option<impl Future<Output = ()>>
+ 678..692 'Some(async {})': Option<impl Future<Output = ()>>
+ 683..691 'async {}': impl Future<Output = ()>
+ 699..707 'join_all': fn join_all<FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>>(FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>) -> JoinAll<<FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>> as IntoIterator>::Item>
+ 699..710 'join_all(x)': JoinAll<impl Future<Output = ()>>
+ 708..709 'x': FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>
"#]],
);
}