diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2025-02-17 09:37:55 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-17 09:37:55 +0000 |
| commit | d7fb8f15c7cfb76eef4ccc17eb00d2222a8ba232 (patch) | |
| tree | 6845bbb1862dd8a24316715e43dcaf3fc1332aef /src/tools | |
| parent | 123f17c57ba3062e6b641fbd089bd6343826ba22 (diff) | |
| parent | 8f8e1c6f08ec25ea42b74c44b0a5c93fffb84610 (diff) | |
| download | rust-d7fb8f15c7cfb76eef4ccc17eb00d2222a8ba232.tar.gz rust-d7fb8f15c7cfb76eef4ccc17eb00d2222a8ba232.zip | |
Merge pull request #19122 from Austaras/master
pass struct fields to chalk
Diffstat (limited to 'src/tools')
3 files changed, 37 insertions, 20 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index c8ff6cba3dd..6d4753ea389 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -768,23 +768,21 @@ pub(crate) fn adt_datum_query( phantom_data, }; - // this slows down rust-analyzer by quite a bit unfortunately, so enabling this is currently not worth it - let _variant_id_to_fields = |id: VariantId| { + let variant_id_to_fields = |id: VariantId| { let variant_data = &id.variant_data(db.upcast()); - let fields = if variant_data.fields().is_empty() { + let fields = if variant_data.fields().is_empty() || bound_vars_subst.is_empty(Interner) { vec![] } else { - let field_types = db.field_types(id); - variant_data - .fields() - .iter() - .map(|(idx, _)| field_types[idx].clone().substitute(Interner, &bound_vars_subst)) - .filter(|it| !it.contains_unknown()) - .collect() + // HACK: provide full struct type info slows down rust-analyzer by quite a bit unfortunately, + // so we trick chalk into thinking that our struct impl Unsize + if let Some(ty) = bound_vars_subst.at(Interner, 0).ty(Interner) { + vec![ty.clone()] + } else { + vec![] + } }; rust_ir::AdtVariantDatum { fields } }; - let variant_id_to_fields = |_: VariantId| rust_ir::AdtVariantDatum { fields: vec![] }; let (kind, variants) = match adt_id { hir_def::AdtId::StructId(id) => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs index 7e7c1f835c7..ef94814d587 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs @@ -535,7 +535,7 @@ fn test() { #[test] fn coerce_unsize_generic() { - check( + check_no_mismatches( r#" //- minicore: coerce_unsized struct Foo<T> { t: T }; @@ -543,9 +543,7 @@ struct Bar<T>(Foo<T>); fn test() { let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; - //^^^^^^^^^^^^^^^^^^^^^ expected &'? Foo<[usize]>, got &'? Foo<[i32; 3]> let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); - //^^^^^^^^^^^^^^^^^^^^^^^^^^ expected &'? Bar<[usize]>, got &'? Bar<[i32; 3]> } "#, ); @@ -957,3 +955,24 @@ fn f() { "#, ); } + +#[test] +fn coerce_nested_unsized_struct() { + check_types( + r#" +//- minicore: fn, coerce_unsized, dispatch_from_dyn, sized +use core::marker::Unsize; + +struct Foo<T: ?Sized>(T); + +fn need(_: &Foo<dyn Fn(i32) -> i32>) { +} + +fn test() { + let callback = |x| x; + //^ i32 + need(&Foo(callback)); +} +"#, + ) +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index dda7bfb2baf..f0eb41b1ce7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -4694,21 +4694,21 @@ fn f<T: Send, U>() { Struct::<T>::IS_SEND; //^^^^^^^^^^^^^^^^^^^^Yes Struct::<U>::IS_SEND; - //^^^^^^^^^^^^^^^^^^^^Yes + //^^^^^^^^^^^^^^^^^^^^{unknown} Struct::<*const T>::IS_SEND; - //^^^^^^^^^^^^^^^^^^^^^^^^^^^Yes + //^^^^^^^^^^^^^^^^^^^^^^^^^^^{unknown} Enum::<T>::IS_SEND; //^^^^^^^^^^^^^^^^^^Yes Enum::<U>::IS_SEND; - //^^^^^^^^^^^^^^^^^^Yes + //^^^^^^^^^^^^^^^^^^{unknown} Enum::<*const T>::IS_SEND; - //^^^^^^^^^^^^^^^^^^^^^^^^^Yes + //^^^^^^^^^^^^^^^^^^^^^^^^^{unknown} Union::<T>::IS_SEND; //^^^^^^^^^^^^^^^^^^^Yes Union::<U>::IS_SEND; - //^^^^^^^^^^^^^^^^^^^Yes + //^^^^^^^^^^^^^^^^^^^{unknown} Union::<*const T>::IS_SEND; - //^^^^^^^^^^^^^^^^^^^^^^^^^^Yes + //^^^^^^^^^^^^^^^^^^^^^^^^^^{unknown} PhantomData::<T>::IS_SEND; //^^^^^^^^^^^^^^^^^^^^^^^^^Yes PhantomData::<U>::IS_SEND; |
