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.rs526
1 files changed, 526 insertions, 0 deletions
diff --git a/crates/hir-ty/src/tests/regression/new_solver.rs b/crates/hir-ty/src/tests/regression/new_solver.rs
new file mode 100644
index 0000000000..f8b73cd505
--- /dev/null
+++ b/crates/hir-ty/src/tests/regression/new_solver.rs
@@ -0,0 +1,526 @@
+use expect_test::expect;
+
+use crate::tests::{check_infer, check_no_mismatches, check_types};
+
+#[test]
+fn regression_20365() {
+ check_infer(
+ r#"
+//- minicore: iterator
+struct Vec<T>(T);
+struct IntoIter<T>(T);
+impl<T> IntoIterator for Vec<T> {
+ type IntoIter = IntoIter<T>;
+ type Item = T;
+}
+impl<T> Iterator for IntoIter<T> {
+ type Item = T;
+}
+
+fn f<T: Space>(a: Vec<u8>) {
+ let iter = a.into_iter();
+}
+
+pub trait Space: IntoIterator {
+ type Ty: Space;
+}
+impl Space for [u8; 1] {
+ type Ty = Self;
+}
+ "#,
+ expect![[r#"
+ 201..202 'a': Vec<u8>
+ 213..246 '{ ...r(); }': ()
+ 223..227 'iter': IntoIter<u8>
+ 230..231 'a': Vec<u8>
+ 230..243 'a.into_iter()': IntoIter<u8>
+ "#]],
+ );
+}
+
+#[test]
+fn regression_19971() {
+ check_infer(
+ r#"
+//- minicore: pointee
+fn make<T>(_thin: *const (), _meta: core::ptr::DynMetadata<T>) -> *const T
+where
+ T: core::ptr::Pointee<Metadata = core::ptr::DynMetadata<T>> + ?Sized,
+{
+ loop {}
+}
+trait Foo {
+ fn foo(&self) -> i32 {
+ loop {}
+ }
+}
+
+fn test() -> i32 {
+ struct F {}
+ impl Foo for F {}
+ let meta = core::ptr::metadata(0 as *const F as *const dyn Foo);
+
+ let f = F {};
+ let fat_ptr = make(&f as *const F as *const (), meta); // <-- infers type as `*const {unknown}`
+
+ let fat_ref = unsafe { &*fat_ptr }; // <-- infers type as `&{unknown}`
+ fat_ref.foo() // cannot 'go to definition' on `foo`
+}
+
+ "#,
+ expect![[r#"
+ 11..16 '_thin': *const ()
+ 29..34 '_meta': DynMetadata<T>
+ 155..170 '{ loop {} }': *const T
+ 161..168 'loop {}': !
+ 166..168 '{}': ()
+ 195..199 'self': &'? Self
+ 208..231 '{ ... }': i32
+ 218..225 'loop {}': !
+ 223..225 '{}': ()
+ 252..613 '{ ...foo` }': i32
+ 300..304 'meta': DynMetadata<dyn Foo + '?>
+ 307..326 'core::...tadata': fn metadata<dyn Foo + '?>(*const (dyn Foo + '?)) -> <dyn Foo + '? as Pointee>::Metadata
+ 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 + 'static)
+ 370..371 'f': F
+ 374..378 'F {}': F
+ 388..395 'fat_ptr': *const (dyn Foo + '?)
+ 398..402 'make': fn make<dyn Foo + '?>(*const (), DynMetadata<dyn Foo + '?>) -> *const (dyn Foo + '?)
+ 398..437 'make(&... meta)': *const (dyn Foo + '?)
+ 403..405 '&f': &'? F
+ 403..417 '&f as *const F': *const F
+ 403..430 '&f as ...nst ()': *const ()
+ 404..405 'f': F
+ 432..436 'meta': DynMetadata<dyn Foo + '?>
+ 489..496 'fat_ref': &'? (dyn Foo + '?)
+ 499..519 'unsafe..._ptr }': &'? (dyn Foo + '?)
+ 508..517 '&*fat_ptr': &'? (dyn Foo + '?)
+ 509..517 '*fat_ptr': dyn Foo + '?
+ 510..517 'fat_ptr': *const (dyn Foo + '?)
+ 560..567 'fat_ref': &'? (dyn Foo + '?)
+ 560..573 'fat_ref.foo()': i32
+ "#]],
+ );
+}
+
+#[test]
+fn regression_19752() {
+ check_no_mismatches(
+ r#"
+//- minicore: sized, copy
+trait T1<T: T2>: Sized + Copy {
+ fn a(self, other: Self) -> Self {
+ other
+ }
+
+ fn b(&mut self, other: Self) {
+ *self = self.a(other);
+ }
+}
+
+trait T2: Sized {
+ type T1: T1<Self>;
+}
+ "#,
+ );
+}
+
+#[test]
+fn regression_type_checker_does_not_eagerly_select_predicates_from_where_clauses() {
+ // This was a very long standing issue (#5514) with a lot of duplicates, that was
+ // fixed by the switch to the new trait solver, so it deserves a long name and a
+ // honorable mention.
+ check_infer(
+ r#"
+//- minicore: from
+
+struct Foo;
+impl Foo {
+ fn method(self) -> i32 { 0 }
+}
+
+fn f<T: Into<Foo>>(u: T) {
+ let x = u.into();
+ x.method();
+}
+ "#,
+ expect![[r#"
+ 38..42 'self': Foo
+ 51..56 '{ 0 }': i32
+ 53..54 '0': i32
+ 79..80 'u': T
+ 85..126 '{ ...d(); }': ()
+ 95..96 'x': Foo
+ 99..100 'u': T
+ 99..107 'u.into()': Foo
+ 113..114 'x': Foo
+ 113..123 'x.method()': i32
+ "#]],
+ );
+}
+
+#[test]
+fn opaque_generics() {
+ check_infer(
+ r#"
+//- minicore: iterator
+pub struct Grid {}
+
+impl<'a> IntoIterator for &'a Grid {
+ type Item = &'a ();
+
+ type IntoIter = impl Iterator<Item = &'a ()>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ }
+}
+ "#,
+ expect![[r#"
+ 150..154 'self': &'a Grid
+ 174..181 '{ }': impl Iterator<Item = &'a ()>
+ "#]],
+ );
+}
+
+#[test]
+fn normalization() {
+ check_infer(
+ r#"
+//- minicore: iterator, iterators
+fn main() {
+ _ = [0i32].into_iter().filter_map(|_n| Some(1i32));
+}
+ "#,
+ expect![[r#"
+ 10..69 '{ ...2)); }': ()
+ 16..17 '_': FilterMap<IntoIter<i32, 1>, impl FnMut(i32) -> Option<i32>>
+ 16..66 '_ = [0...1i32))': ()
+ 20..26 '[0i32]': [i32; 1]
+ 20..38 '[0i32]...iter()': IntoIter<i32, 1>
+ 20..66 '[0i32]...1i32))': FilterMap<IntoIter<i32, 1>, impl FnMut(i32) -> Option<i32>>
+ 21..25 '0i32': i32
+ 50..65 '|_n| Some(1i32)': impl FnMut(i32) -> Option<i32>
+ 51..53 '_n': i32
+ 55..59 'Some': fn Some<i32>(i32) -> Option<i32>
+ 55..65 'Some(1i32)': Option<i32>
+ 60..64 '1i32': i32
+ "#]],
+ );
+}
+
+#[test]
+fn regression_20487() {
+ check_no_mismatches(
+ r#"
+//- minicore: coerce_unsized, dispatch_from_dyn
+trait Foo {
+ fn bar(&self) -> u32 {
+ 0xCAFE
+ }
+}
+
+fn debug(_: &dyn Foo) {}
+
+impl Foo for i32 {}
+
+fn main() {
+ debug(&1);
+}"#,
+ );
+}
+
+#[test]
+fn projection_is_not_associated_type() {
+ check_no_mismatches(
+ r#"
+//- minicore: fn
+trait Iterator {
+ type Item;
+
+ fn partition<F>(self, f: F)
+ where
+ F: FnMut(&Self::Item) -> bool,
+ {
+ }
+}
+
+struct Iter;
+impl Iterator for Iter {
+ type Item = i32;
+}
+
+fn main() {
+ Iter.partition(|n| true);
+}
+ "#,
+ );
+}
+
+#[test]
+fn cast_error_type() {
+ check_infer(
+ r#"
+fn main() {
+ let foo: [_; _] = [false] as _;
+}
+ "#,
+ expect![[r#"
+ 10..47 '{ le...s _; }': ()
+ 18..21 'foo': [bool; 1]
+ 32..39 '[false]': [bool; 1]
+ 32..44 '[false] as _': [bool; 1]
+ 33..38 'false': bool
+ "#]],
+ );
+}
+
+#[test]
+fn no_infinite_loop_on_super_predicates_elaboration() {
+ check_infer(
+ r#"
+//- minicore: sized
+trait DimMax<Other: Dimension> {
+ type Output: Dimension;
+}
+
+trait Dimension: DimMax<<Self as Dimension>:: Smaller, Output = Self> {
+ type Smaller: Dimension;
+}
+
+fn test<T, U>(t: T)
+where
+ T: DimMax<U>,
+ U: Dimension,
+{
+ let t: <T as DimMax<U>>::Output = loop {};
+}
+"#,
+ expect![[r#"
+ 182..183 't': T
+ 230..280 '{ ... {}; }': ()
+ 240..241 't': <T as DimMax<U>>::Output
+ 270..277 'loop {}': !
+ 275..277 '{}': ()
+ "#]],
+ )
+}
+
+#[test]
+fn fn_coercion() {
+ check_no_mismatches(
+ r#"
+fn foo() {
+ let _is_suffix_start: fn(&(usize, char)) -> bool = match true {
+ true => |(_, c)| *c == ' ',
+ _ => |(_, c)| *c == 'v',
+ };
+}
+ "#,
+ );
+}
+
+#[test]
+fn coercion_with_errors() {
+ check_no_mismatches(
+ r#"
+//- minicore: unsize, coerce_unsized
+fn foo(_v: i32) -> [u8; _] { loop {} }
+fn bar(_v: &[u8]) {}
+
+fn main() {
+ bar(&foo());
+}
+ "#,
+ );
+}
+
+#[test]
+fn another_20654_case() {
+ check_no_mismatches(
+ r#"
+//- minicore: sized, unsize, coerce_unsized, dispatch_from_dyn, fn
+struct Region<'db>(&'db ());
+
+trait TypeFoldable<I: Interner> {}
+
+trait Interner {
+ type Region;
+ type GenericArg;
+}
+
+struct DbInterner<'db>(&'db ());
+impl<'db> Interner for DbInterner<'db> {
+ type Region = Region<'db>;
+ type GenericArg = GenericArg<'db>;
+}
+
+trait GenericArgExt<I: Interner<GenericArg = Self>> {
+ fn expect_region(&self) -> I::Region {
+ loop {}
+ }
+}
+impl<'db> GenericArgExt<DbInterner<'db>> for GenericArg<'db> {}
+
+enum GenericArg<'db> {
+ Region(Region<'db>),
+}
+
+fn foo<'db, T: TypeFoldable<DbInterner<'db>>>(arg: GenericArg<'db>) {
+ let regions = &mut || arg.expect_region();
+ let f: &'_ mut (dyn FnMut() -> Region<'db> + '_) = regions;
+}
+ "#,
+ );
+}
+
+#[test]
+fn trait_solving_with_error() {
+ check_infer(
+ r#"
+//- minicore: size_of
+struct Vec<T>(T);
+
+trait Foo {
+ type Item;
+ fn to_vec(self) -> Vec<Self::Item> {
+ loop {}
+ }
+}
+
+impl<'a, T, const N: usize> Foo for &'a [T; N] {
+ type Item = T;
+}
+
+fn to_bytes() -> [u8; _] {
+ loop {}
+}
+
+fn foo() {
+ let _x = to_bytes().to_vec();
+}
+ "#,
+ expect![[r#"
+ 60..64 'self': Self
+ 85..108 '{ ... }': Vec<<Self as Foo>::Item>
+ 95..102 'loop {}': !
+ 100..102 '{}': ()
+ 208..223 '{ loop {} }': [u8; _]
+ 214..221 'loop {}': !
+ 219..221 '{}': ()
+ 234..271 '{ ...c(); }': ()
+ 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>
+ "#]],
+ );
+}
+
+#[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);
+}
+"#,
+ );
+}