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.rs | 420 |
1 files changed, 420 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..ead79a8f5b --- /dev/null +++ b/crates/hir-ty/src/tests/regression/new_solver.rs @@ -0,0 +1,420 @@ +use expect_test::expect; + +use crate::tests::{check_infer, check_no_mismatches}; + +#[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 + '?) + 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> + "#]], + ); +} |