Unnamed repository; edit this file 'description' to name the repository.
Fix: use `FnAbi::Rust` for tuple struct/enum constructors and align `is_rust()` with rustc
Albab-Hasan 7 weeks ago
parent a96b6a9 · commit 3a619aa
-rw-r--r--crates/hir-ty/src/lower.rs4
-rw-r--r--crates/hir-ty/src/next_solver/abi.rs3
-rw-r--r--crates/hir-ty/src/tests/traits.rs34
3 files changed, 37 insertions, 4 deletions
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 1290874177..bb126f16ff 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -2468,7 +2468,7 @@ fn fn_sig_for_struct_constructor(
let inputs_and_output =
Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret.as_ref())));
StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::dummy(FnSig {
- abi: FnAbi::RustCall,
+ abi: FnAbi::Rust,
c_variadic: false,
safety: Safety::Safe,
inputs_and_output,
@@ -2487,7 +2487,7 @@ fn fn_sig_for_enum_variant_constructor(
let inputs_and_output =
Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret.as_ref())));
StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::dummy(FnSig {
- abi: FnAbi::RustCall,
+ abi: FnAbi::Rust,
c_variadic: false,
safety: Safety::Safe,
inputs_and_output,
diff --git a/crates/hir-ty/src/next_solver/abi.rs b/crates/hir-ty/src/next_solver/abi.rs
index 80d1ea4aa4..1813abab86 100644
--- a/crates/hir-ty/src/next_solver/abi.rs
+++ b/crates/hir-ty/src/next_solver/abi.rs
@@ -62,7 +62,6 @@ impl<'db> rustc_type_ir::inherent::Abi<DbInterner<'db>> for FnAbi {
}
fn is_rust(self) -> bool {
- // TODO: rustc does not consider `RustCall` to be true here, but Chalk does
- matches!(self, FnAbi::Rust | FnAbi::RustCall)
+ matches!(self, FnAbi::Rust)
}
}
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index cdf7b40003..74e9a8dac0 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -2218,6 +2218,40 @@ fn test() {
}
#[test]
+fn tuple_struct_constructor_as_fn_trait() {
+ check_types(
+ r#"
+//- minicore: fn
+struct S(u32, u64);
+
+fn takes_fn<F: Fn(u32, u64) -> S>(f: F) -> S { f(1, 2) }
+
+fn test() {
+ takes_fn(S);
+ //^^^^^^^^^^^ S
+}
+"#,
+ );
+}
+
+#[test]
+fn enum_variant_constructor_as_fn_trait() {
+ check_types(
+ r#"
+//- minicore: fn
+enum E { A(u32) }
+
+fn takes_fn<F: Fn(u32) -> E>(f: F) -> E { f(1) }
+
+fn test() {
+ takes_fn(E::A);
+ //^^^^^^^^^^^^^^ E
+}
+"#,
+ );
+}
+
+#[test]
fn fn_item_fn_trait() {
check_types(
r#"